React生命周期及事件详解
Posted 编程之间
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React生命周期及事件详解相关的知识,希望对你有一定的参考价值。
一、组件的详细说明和生命周期ComponentSpecs and Lifecycle
组件的详细说明(Component Specifications)
当通过调用 React.createClass() 来创建组件的时候,你应该提供一个包含 render 方法的对象,并且也可以包含其它的在这里描述的生命周期方法。
render
ReactComponent render()
render() 方法是必须的。
当调用的时候,会检测 this.props 和 this.state,返回一个单子级组件。该子级组件可以是虚拟的本地DOM 组件(比如 <div /> 或者 React.DOM.div()),也可以是自定义的复合组件。
你也可以返回 null 或者 false 来表明不需要渲染任何东西。实际上,React渲染一个<noscript> 标签来处理当前的差异检查逻辑。当返回 null 或者 false 的时候,this.getDOMNode() 将返回 null。
render() 函数应该是纯粹的,也就是说该函数不修改组件state,每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如通过使用 setTimeout)。如果需要和浏览器交互,在 componentDidMount() 中或者其它生命周期方法中做这件事。保持render() 纯粹,可以使服务器端渲染更加切实可行,也使组件更容易被理解。
getInitialState
object getInitialState()
在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
getDefaultProps
object getDefaultProps()
在组件类创建的时候调用一次,然后返回值被缓存下来。如果父组件没有指定props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props (使用 in 检测属性)。
该方法在任何实例创建之前调用,因此不能依赖于 this.props。另外,getDefaultProps() 返回的任何复杂对象将会在实例间共享,而不是每个实例拥有一份拷贝。
propTypes
object propTypes
propTypes 对象允许验证传入到组件的props。更多关于 propTypes 的信息,参考可重用的组件。
mixins
array mixins
mixin 数组允许使用混合来在多个组件之间共享行为。更多关于混合的信息,参考可重用的组件。
statics
object statics
statics 对象允许你定义静态的方法,这些静态的方法可以在组件类上调用。例如:
var MyComponent=React.createClass(
statics:
customMethod: function(foo)
return foo==='bar';
,
render:function()
);
MyComponent.customMethod('bar'); // true
在这个块儿里面定义的方法都是静态的,意味着你可以在任何组件实例创建之前调用它们,这些方法不能获取组件的props 和 state。如果你想在静态方法中检查 props 的值,在调用处把 props 作为参数传入到静态方法。
displayName
string displayName
displayName 字符串用于输出调试信息。JSX自动设置该值;参考JSX 深入。
生命周期方法
许多方法在组件生命周期中某个确定的时间点执行。
挂载: componentWillMount
componentWillMount()
服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。如果在这个方法内调用setState,render() 将会感知到更新后的state,将会执行仅一次,尽管 state 改变了。
挂载: componentDidMount
componentDidMount()
在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。在生命周期中的这个时间点,组件拥有一个DOM 展现,你可以通过 this.getDOMNode() 来获取相应 DOM 节点。
如果想和其它javascript 框架集成,使用 setTimeout 或者 setInterval 来设置定时器,或者发送 AJAX请求,可以在该方法中执行这些操作。
注意:
为了兼容 v0.9,DOM节点作为最后一个参数传入。你依然可以通过this.getDOMNode() 获取 DOM 节点。
更新: componentWillReceiveProps
componentWillReceiveProps(object nextProps)
在组件接收到新的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。
更新: shouldComponentUpdate
booleanshouldComponentUpdate(object nextProps, object nextState)
在接收到新的props 或者 state,将要渲染之前调用。该方法在初始化渲染的时候不会调用,在使用 forceUpdate 方法的时候也不会。
如果确定新的props 和 state 不会导致组件更新,则此处应该 返回 false。
shouldComponentUpdate:function(nextProps,nextState)
return nextProps.id!== this.props.id;
如果 shouldComponentUpdate 返回false,则 render() 将不会执行,直到下一次 state 改变。(另外,componentWillUpdate 和 componentDidUpdate 也不会被调用。)
默认情况下,shouldComponentUpdate 总会返回true,在 state 改变的时候避免细微的bug,但是如果总是小心地把 state 当做不可变的,在 render() 中只从 props 和state 读取值,此时你可以覆盖 shouldComponentUpdate 方法,实现新老 props 和state 的比对逻辑。
如果性能是个瓶颈,尤其是有几十个甚至上百个组件的时候,使用 shouldComponentUpdate可以提升应用的性能。
更新: componentWillUpdate
componentWillUpdate(object nextProps, object nextState)
在接收到新的props 或者 state 之前立刻调用。在初始化渲染的时候该方法不会被调用。
使用该方法做一些更新之前的准备工作。
注意:
你不能在刚方法中使用 this.setState()。如果需要更新 state 来响应某个 prop 的改变,请使用 componentWillReceiveProps。
更新: componentDidUpdate
componentDidUpdate(object prevProps, object prevState)
在组件的更新已经同步到DOM 中之后立刻被调用。该方法不会在初始化渲染的时候调用。
使用该方法可以在组件更新之后操作DOM 元素。
注意:
为了兼容 v0.9,DOM节点会作为最后一个参数传入。如果使用这个方法,你仍然可以使用 this.getDOMNode() 来访问 DOM 节点。
移除: componentWillUnmount
componentWillUnmount()
在组件从DOM 中移除的时候立刻被调用。
在该方法中执行任何必要的清理,比如无效的定时器,或者清除在 componentDidMount 中创建的 DOM 元素。
二、组件API
ReactComponent
React组件实例在渲染的时候创建。这些实例在接下来的渲染中被重复使用,可以在组件方法中通过 this 访问。唯一一种在 React 之外获取 React组件实例句柄的方式就是保存React.render 的返回值。在其它组件内,可以使用 refs 得到相同的结果。
setState
setState(object nextState[,function callback])
合并nextState 和当前 state。这是在事件处理函数中和请求回调函数中触发 UI 更新的主要方法。另外,也支持可选的回调函数,该函数在 setState 执行完毕并且组件重新渲染完成之后调用。
注意:
绝对不要直接改变 this.state,因为在之后调用 setState() 可能会替换掉你做的更改。把 this.state 当做不可变的。
setState() 不会立刻改变 this.state,而是创建一个即将处理的 state 转变。在调用该方法之后获取 this.state 的值可能会得到现有的值,而不是最新设置的值。
不保证 setState() 调用的同步性,为了提升性能,可能会批量执行 state 转变和 DOM 渲染。
setState() 将总是触发一次重绘,除非在 shouldComponentUpdate() 中实现了条件渲染逻辑。如果使用可变的对象,但是又不能在 shouldComponentUpdate() 中实现这种逻辑,仅在新 state 和之前的 state存在差异的时候调用 setState() 可以避免不必要的重新渲染。
replaceState
replaceState(object nextState[,function callback])
类似于 setState(),但是删除之前所有已存在的 state键,这些键都不在 nextState 中。
forceUpdate()
forceUpdate([function callback])
如果 render() 方法从 this.props 或者 this.state 之外的地方读取数据,你需要通过调用 forceUpdate() 告诉 React什么时候需要再次运行 render()。如果直接改变了this.state,也需要调用 forceUpdate()。
调用 forceUpdate() 将会导致 render() 方法在相应的组件上被调用,并且子级组件也会调用自己的 render(),但是如果标记改变了,那么 React仅会更新 DOM。
通常情况下,应该尽量避免所有使用 forceUpdate() 的情况,在 render() 中仅从this.props 和 this.state 中读取数据。这会使应用大大简化,并且更加高效。
getDOMNode
DOMElement getDOMNode()
如果组件已经挂载到了DOM 上,该方法返回相应的本地浏览器 DOM 元素。从 DOM 中读取值的时候,该方法很有用,比如获取表单字段的值和做一些 DOM 操作。当 render 返回null 或者 false 的时候,this.getDOMNode() 返回 null。
isMounted()
bool isMounted()
如果组件渲染到了DOM 中,isMounted() 返回true。可以使用该方法保证 setState() 和forceUpdate() 在异步场景下的调用不会出错。
setProps
setProps(object nextProps[,function callback])
当和一个外部的JavaScript 应用集成的时候,你可能想给一个用 React.render() 渲染的组件打上改变的标记。
尽管在同一个节点上再次调用 React.render() 来更新根组件是首选的方式,也可以调用setProps() 来改变组件的属性,触发一次重新渲染。另外,可以传递一个可选的回调函数,该函数将会在 setProps 完成并且组件重新渲染完成之后调用。
注意:
When possible,the declarative approach of calling React.render() againis preferred; it tends to make updates easier to reason about. (There's nosignificant performance difference between the two approaches.)
刚方法仅在根组件上面调用。也就是说,仅在直接传给 React.render() 的组件上可用,在它的子级组件上不可用。如果你倾向于在子组件上使用 setProps(),不要利用响应式更新,而是当子组件在 render() 中创建的时候传入新的prop 到子组件中。
replaceProps
replaceProps(object nextProps[,function callback])
类似于 setProps(),但是删除所有已存在的props,而不是合并新旧两个 props 对象。
三、组件的详细说明和生命周期(ComponentSpecs and Lifecycle)
组件的详细说明(Component Specifications)
当通过调用 React.createClass() 来创建组件的时候,你应该提供一个包含 render 方法的对象,并且也可以包含其它的在这里描述的生命周期方法。
render
ReactComponent render()
render() 方法是必须的。
当调用的时候,会检测 this.props 和 this.state,返回一个单子级组件。该子级组件可以是虚拟的本地DOM 组件(比如 <div /> 或者 React.DOM.div()),也可以是自定义的复合组件。
你也可以返回 null 或者 false 来表明不需要渲染任何东西。实际上,React渲染一个<noscript> 标签来处理当前的差异检查逻辑。当返回 null 或者 false 的时候,this.getDOMNode() 将返回 null。
render() 函数应该是纯粹的,也就是说该函数不修改组件state,每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如通过使用 setTimeout)。如果需要和浏览器交互,在 componentDidMount() 中或者其它生命周期方法中做这件事。保持render() 纯粹,可以使服务器端渲染更加切实可行,也使组件更容易被理解。
getInitialState
object getInitialState()
在组件挂载之前调用一次。返回值将会作为 this.state 的初始值。
getDefaultProps
object getDefaultProps()
在组件类创建的时候调用一次,然后返回值被缓存下来。如果父组件没有指定props 中的某个键,则此处返回的对象中的相应属性将会合并到 this.props (使用 in 检测属性)。
该方法在任何实例创建之前调用,因此不能依赖于 this.props。另外,getDefaultProps() 返回的任何复杂对象将会在实例间共享,而不是每个实例拥有一份拷贝。
propTypes
object propTypes
propTypes 对象允许验证传入到组件的props。更多关于 propTypes 的信息,参考可重用的组件。
mixins
array mixins
mixin 数组允许使用混合来在多个组件之间共享行为。更多关于混合的信息,参考可重用的组件。
statics
object statics
statics 对象允许你定义静态的方法,这些静态的方法可以在组件类上调用。例如:
var MyComponent=React.createClass(
statics:
customMethod: function(foo)
return foo==='bar';
,
render:function()
);
MyComponent.customMethod('bar'); // true
在这个块儿里面定义的方法都是静态的,意味着你可以在任何组件实例创建之前调用它们,这些方法不能获取组件的props 和 state。如果你想在静态方法中检查 props 的值,在调用处把 props 作为参数传入到静态方法。
displayName
string displayName
displayName 字符串用于输出调试信息。JSX自动设置该值;参考JSX 深入。
生命周期方法
许多方法在组件生命周期中某个确定的时间点执行。
挂载: componentWillMount
componentWillMount()
服务器端和客户端都只调用一次,在初始化渲染执行之前立刻调用。如果在这个方法内调用setState,render() 将会感知到更新后的state,将会执行仅一次,尽管 state 改变了。
挂载: componentDidMount
componentDidMount()
在初始化渲染执行之后立刻调用一次,仅客户端有效(服务器端不会调用)。在生命周期中的这个时间点,组件拥有一个DOM 展现,你可以通过 this.getDOMNode() 来获取相应 DOM 节点。
如果想和其它JavaScript 框架集成,使用 setTimeout 或者 setInterval 来设置定时器,或者发送 AJAX请求,可以在该方法中执行这些操作。
注意:
为了兼容 v0.9,DOM节点作为最后一个参数传入。你依然可以通过this.getDOMNode() 获取 DOM 节点。
更新: componentWillReceiveProps
componentWillReceiveProps(object nextProps)
在组件接收到新的props 的时候调用。在初始化渲染的时候,该方法不会调用。
React 生命周期(新旧)及 案例