这是React分类下的第一篇文章,是在了解了一些基本面后,看Tyler文章,边看边理解边写的。react
React能够看作是MVC中的V,关注的是视图层。React的组件就像Angular的Directive,包括了HTML,CSS,JS以及相关数据等。React的组件被定义在了以"JSX"为后缀的文件中,这些JSX文件会被最终编译成Javascript文件。数组
来看一个最基本的写法:app
var HelloWorld = React.createClass({ render: function(){ return ( <div> Hello World! </div> ) } }); ReactDOM.render(<HelloWorld />, document.getElementBy('app'));
以上,咱们能够了解到:dom
React.createClass
用来建立组件,接收一个object,render字段必须有ReactDOM.render
来渲染组件,该方法接收2个参数,一个参数表明组件,另外一个表明渲染的位置<div>Hello World!</div>
和一般的HTML代码不同,是放在以jsx为后缀的文件中的,最终会被转换成一个Javascript对象,最终React会建立一个"virtual DOM",React会经过React.createElement("div", null, "Hello Wolrd")
建立虚拟的DOM。→ 检查数据发生变化的部分
→ 从新渲染virutal DOM
→ 与上一次的virtual DOM进行比较
→ 在实际DOM上只更新发生变化的部分ide
var HelloUser = React.createClass({ getInitialState: function(){ return { username: 'firstusername' } }, render: function(){ return ( <div> Hello {this.state.username} </div> ) } });
getInitialState
方法返回object对象,为state中的字段赋值this.state.字段名
来获取字段状态setState
虽然在上面没有说起,但这个方法时被用来真正设置组件状态的。并且这个setState
方法是最经常使用的,当页面有数据变化,Reacct会触发setState
方法,渲染virtual DOM,与上一次的virtual DOM进行比较,最后更新发生变化的部分。2.1 经过事件改变状态函数
以上,是经过getInitialState
方法设置了一个初始状态,如何经过事件来触发改变状态呢?好比有一个<input>
,经过它的onChange
方法来触发改变状态。ui
var HelloUser = React.creatClass({ getInitialState: function(){ return { username: 'darren' } }, handleChange: function(e){ this.setState({ usename: e.target.value }); }, render: function(){ return ( <div> Hello {this.state.username}<br/> Change Name:<input type="text" value={this.state.username} onChange={this.handleChange}> </div> ) } });
handleChange
方法中,经过setState
改变变量的状态,接着,React渲染一个新的virtual DOM, 与上一次的virtual DOM比较差别,最后只更新发生变化的那部分DOMonChange
方法用来触发事件2.2 嵌套组件的状态传递this
如今,咱们知道了如何设置组件的初始状态,也知道如何如何设置组件的状态,如今来到另一个话题:当主键有嵌套的时候,如何把父组件的状态传递给子组件呢?code
先来看没有组件嵌套的状况:component
var HelloUser = React.createClass({ render: function(){ return ( <div> Hello, {this.props.name}</div> ) } }); ReactDOM.render(<HelloUser name="darren" />, document.getElementById('app'));
<HelloUser />
,组件中的变量,好比这里的name字段,在jsx语法中是以属性名存在的,好比这里的<HelloUser name="darren">
<HelloUser name="darren" />
就是须要渲染的组件,HelloUser就是组件的名称,给name赋的值最终赋值给了props属性再来看存在组件嵌套的状况下,如何传递State。
被嵌套的组件:
var ShowList = React.createClass({ render: function(){ var listItems = this.props.names.map(function(friend){ return <li>{{friend}}</li>; }); return ( <div> <h3>Friends</h3> <ul> {listItems} </ul> </div> ) } });
以上,ShowList组件的视图渲染须要外界给names字段赋上数组。也就是<ShowList names=... />
中names属性须要赋值。从哪里赋值呢?能够从嵌套组件的state中获取。
好,那就来到嵌套组件:
var ParentContainer = React.createClass({ getIntitialState: function(){ return { name: 'darren', friends:['a','bob'] } }, render: function(){ return ( <div> <h3>Name: {this.state.name}</h3> <ShowList names={this.state.friends}> </div> ) } });
getIntitialState
中返回对象的各个字段是放在了state中的如今,组件看起来就像C#中对类的封装。React的组件是否和C#中的类有更多的类似性呢?
假设,在显示朋友列表的页面再增长一块区域,用来添加朋友信息。那,咱们有必要为这一块添加的区域定义一个组件:
var AddFriend = React.createClas({ getIntialState: function(){ return { newFriend: '' } }, updateNewFriend: function(e){//更新就是为state的newFriend字段赋上当前的值 this.setState({ newFriend: e.target.value }); }, handleAddNew: function(){ this.props.addNew(this.state.newFriend); this.setState({ newFriend: '' }); }, render: function(){ return ( <div> <input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} /> <button onClick={this.handleAddNew}>Add Friend</button> </div> ) } });
<AddFriend addNew={...} />
这样的形式呈现以上的AddFriend组件是也是一个被嵌套组件,它和ShowList组件被一块儿嵌套在ParentContainer这个组件中。
因而,就来到了ParentContainer这个组件。
var ParentContainer = React.createClass({ getInitialState: function(){ return { name: 'darren', friends: ['a','b'] } }, addFriend: function(friend){ this.setState({ this.setState({ friends: this.state.friends.concat([friend]) }); }); }, render: function(){ return ( <div> <h3>Name: {this.state.name}</h3> <AddFriend addNew={this.addFriend} /> <ShowList names={this.state.friends} /> </div> ) } });
被嵌套组件所须要的,都经过嵌套组件的state或函数得到。
2.3 设置组件的属性类型
在上面的AddFriend组件中,button是这样的:<button onClick={this.handleAddNew}>Add Friend</button>
,button的点击事件由handleAddNew函数决定,而handleAddNew函数由this.props.addNew(this.state.newFriend)
所决定,addNew函数是props属性的函数类型字段,是否能够定义呢?答案是能够。
var AddFriend = React.createClas({ getIntialState: function(){ return { newFriend: '' } }, propTypes: { addNew: React.PropTypes.func.isRequired }, updateNewFriend: function(e){//更新就是为state的newFriend字段赋上当前的值 this.setState({ newFriend: e.target.value }); }, handleAddNew: function(){ this.props.addNew(this.state.newFriend); this.setState({ newFriend: '' }); }, render: function(){ return ( <div> <input type="text" value={this.state.newFriend} onChange={this.updateNewFriend} /> <button onClick={this.handleAddNew}>Add Friend</button> </div> ) } });
组件的生命周期又是怎样的呢?
var FriendsConainer = React.createClass({ getInitialState: function(){ alert('getInitialState'); return { name: 'darren' } }, componentWillMount: function(){}, componentDidMount: function(){}, componentWillReceiveProps: function(nextProps){}, componentWillUnmount: function(){}, render: function(){ return ( <div> Hello, {this.state.name} </div> ) } });