@(React学习)javascript
React 容许将代码封装成组件(component),而后像插入普通 HTML 标签同样,在网页中插入这个组件。html
组件类只能包含一个顶层标签,不然会报错。java
var HelloXiaowang = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } }); ReactDOM.render( <HelloXiaowang name="junyan" />, document.getElementById('shuaige') );
上面代码中,变量 HelloXiaowang 就是一个组件类。模板插入 HelloXiaowang /> 时,会自动生成 HelloXiaowang 的一个实例(下文的"组件"都指组件类的实例)。react
全部组件类都必须有本身的render方法,用于输出组件
ReactElement render ( )git
当调用的时候,会检测 this.props 和 this.state,返回一个单子级组件。该子级组件能够是虚拟的本地 DOM 组件(好比 div /> 或者 React.DOM.div()),也能够是自定义的复合组件。github
var HelloXiaowang = React.createClass({ render: function() { return <h1>Hello {this.props.name}</h1>; } });
render ( ) 函数应该是纯粹的,也就是说该函数不修改组件 s浏览器
tate,每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如经过使用 setTimeout)。若是须要和浏览器交互,在 componentDidMount() 中或者其它生命周期方法中作这件事。保持 render() 纯粹,可使服务器端渲染更加切实可行,也使组件更容易被理解。服务器
组件本质上是状态机,输入肯定,输出必定肯定app
状态机本质上是状态与转移的结合。当状态发生转换时会触发不一样的钩子函数,从而让开发者有机会作出相应。
组件的声明周期分红三个状态:函数
Mounting:初始化阶段(已插入真实 DOM)
Updating:运行中阶段(正在被从新渲染)
Unmounting:销毁阶段(已移出真实 DOM)
类建立完成以后,就能够进行实例化。
getDefaultProps: 只调用一次,实例之间共享引用
getInitialState: 初始化每一个实例特有的状态
componentWillMount: render
以前最后一次修改状态的机会。若是在这个方法内调用setState
,render()
将会感知到更新后的state
,将会执行仅一次,尽管state
改变了。
render: 只能访问this.props和this.state,只有一个顶层组件,不容许修改状态和DOM输出
componentDidMount: 成功render并渲染完成真实DOM以后触发,能够修改DOM
当组件在客户端被实例化,第一次被建立时,如下方法依次被调用:
getDefaultProps
getInitialState
componentWillMount
render
componentDidMount
当组件在服务端被实例化,首次被建立时,如下方法依次被调用:
getDefaultProps
getInitialState
componentWillMount
render
componentDidMount 不会在服务端被渲染的过程当中调用。
getDefaultProps方法不是在组件建立的时候调用,而是在createClass时调用。
var count = 0; var HelloWorld = React.createClass({ getDefaultProps:function(){ return {name:"dada"}; }, getInitialState:function(){ return { myCount:count++, ready:false }; }, componentWillMount:function(){ this.setState({ready:true}); }, render:function(){ return <p>Hello,{this.props.name?this.props.name:"World"} <br/>{''+this.props.ready}{this.state.myCount}</p>; }, componentDidMount:function(){ $(ReactDOM.findDOMNode(this)).append("bianke"); } }); ReactDOM.render(<HelloWorld/>,document.getElementById('shuage'))
阮老师例子:
var Hello = React.createClass({ getInitialState: function () { return { opacity: 1.0 }; }, componentDidMount: function () { this.timer = setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } this.setState({ opacity: opacity }); }.bind(this), 100); }, render: function () { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ); } }); ReactDOM.render( <Hello name="world"/>, document.body );
上面代码在hello组件加载之后,经过 componentDidMount 方法设置一个定时器,每隔100毫秒,就从新设置组件的透明度,从而引起从新渲染。
另外组件的style属性的设置方式要写成
style={{opacity: this.state.opacity}}
React.findDOMNode()
若是这个组件已经被初始化到DOM中,这个方法返回相应的原生浏览器的DOM元素。这个方法用于读取这个DOM的值,例如表单的值与DOM的方法。在多数状况下附加一个ref
属性与DOM节点上,用来避免使用findDOMNode
。当render
返回null或false时,findDOMNode
也返回null。
注意:
findDOMNode
是一个用来访问底层DOM节点的出口。在大多数状况下,是不鼓励用出口,由于他穿过了组件的层
findDOMNode
仅仅是在初始化阶段的组件起做用(由于组件已经存在于DOM结构中)。若是你尝试在还没有在初始化阶段的组件中调用这个方法(就像render()函数中组件还没有建立就调用这个方法)会抛出异常。
findDOMNode
不能用于没有状态的组件中。
getDOMNode
已过期,不建议使用。
此时组件已经渲染好而且用户能够与它进行交互,好比鼠标点击,手指点按,或者其它的一些事件,致使应用状态的改变
componentWillReceiveProps:父组件修改属性触发,能够修改新属性、修改状态。它是在组件发生改变以前触发
shouldComponentUpdate:返回false会阻止render调用
componentWillUpdate:不能修改属性与状态
render: 只能访问this.props和this.state,只有一个顶层组件,不容许修改状态和DOM输出
componentDidUpdate:能够修改DOM
在组件接收到新的 props 的时候调用。在初始化渲染的时候,该方法不会调用。
用此函数能够做为 react 在 prop 传入以后, render()
渲染以前更新 state 的机会。老的 props 能够经过this.props
获取到。在该函数调用用this.setState()
将不会引发第二次渲染。
componentWillReceiveProps: function(nextProps) { this.setState({ likesIncreasing: nextProps.likeCount > this.props.likeCount }); }
对于 state,没有类似的方法:
componentWillReceiveState
。将要传进来的 prop 可能会引发 state 改变,反之则否则。若是须要在 state 改变的时候执行一些操做,请使componentWillUpdate
。
在接收到新的 props 或者 state,将要渲染以前调用。该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。
若是肯定新的 props 和 state 不会致使组件更新,则此处应该 返回 false。
shouldComponentUpdate: function(nextProps, nextState) { return nextProps.id !== this.props.id; }
若是shouldComponentUpdate
返回 false,则render()
将不会执行,直到下一次 state 改变。
若是性能是个瓶颈,尤为是有几十个甚至上百个组件的时候,使用
shouldComponentUpdate
能够提高应用的性能。
默认状况下shouldComponentUpdate
总会返回 true,在 state 改变的时候避免细微的 bug,可是若是老是当心地把 state 当作不可变的,在render()
中只从 props 和 state 读取值,此时你能够覆盖shouldComponentUpdate
方法,实现新老 props 和 state 的比对逻辑。
在接收到新的 props 或者 state 以前马上调用。在初始化渲染的时候该方法不会被调用。使用该方法作一些更新以前的准备工做。
你不能在此方法中使用
this.setState()
。若是须要更新 state 来响应某个 prop 的改变,请使用componentWillReceiveProps
。
在组件的更新已经同步到 DOM 中以后马上被调用。该方法不会在初始化渲染的时候调用。使用该方法能够在组件更新以后操做 DOM 元素。
每次修改 state,都会从新渲染组件,实例化后经过 state 更新组件,会依次调用下列方法:
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
可是不要直接修改 this.state,要经过 this.setState 方法来修改。
正确用法
var HelloXianrou = React.createClass({ componentWillReceiveProps:function(newProps){ console.log(newProps); }, render:function () { console.log(4); return <p>Hello {this.props.name||"World"}</p> }, componentDidUpdate:function () { $(ReactD.findDOMNode(this)).append("<p>大大是大帅哥</p>") } }); var HelloDada = React.createClass({ getInitialState:function () { return {name:''}; }, handleChange:function (e) { this.setState({name:e.target.value}); }, render:function () { return <div> <HelloXianrou name={this.state.name}></HelloXianrou> <br/> <input type="text" onChange={this.handleChange} /> </div> } }); ReactDOM.render(<HelloDada></HelloDada>,document.getElementById('reactDemo'))
componentWillUnmount
:在删除组件以前进行清理操做,好比计时器和事件监听器。或者清除在 componentDidMount 中建立的 DOM 元素。
移除一个已经初始化DOM过的React组件,清理它的操做和状态。若是这个组件中没有初始化过的组件,这个方法没有任何做用。若是这个组件被销毁则返回true,反之返回false
var HelloXianrou = React.createClass({ render:function () { console.log(4); return <p>Hello {this.props.name||"World"}</p> }, componentWillUnmount:function () { console.log("Booooooooooom!!") } }); var HelloDada = React.createClass({ getInitialState:function () { return {name:''}; }, handleChange:function (e) { /* if (e.target.value == "123") { React.unmountComponentAtNode(document.getElementById('reactDemo')[0]); return; } */ this.setState({name:e.target.value}); }, render:function () { /* if(this.state.name == "123"){ return <p>123</p> } */ return <div> <HelloXianrou name={this.state.name}></HelloXianrou> <br/> <input type="text" onChange={this.handleChange} /> </div> } }); ReactDOM.render(<HelloDada></HelloDada>,document.getElementById('reactDemo'))
本文主要介绍了组件的生命周期。许多方法在组件生命周期中某个肯定的时间点执行。