16. react组件生命周期(react component
三个阶段:装载,更新,销毁
生命周期(组件内在其某些阶段自动执行的函数)
粉红色--早期的生命周期中的方法
橙色--即将被淘汰的方法
蓝色--新增的方法
方法简介:
装载/初始化:
createClass
调用 React.createClass,即创建组件类的时候,会触发getDefaultProps 方法,该方法返回一个对象,然后与父组件指定的props对象合并,最后赋值给 this.props 作为该组件的默认属性,该方法只调用一次
getDefaultProps
getDefaultProps 方法可以用来设置组件属性的默认值,在组件被建立时候就立即调用,所有实例都可以共享这些属性。此时并不可以使用this.state和setState。
注意es6语法中就不这样用了,在前面一篇文章中介绍过了区别。
getInitialState
getInitialState 方法用于定义初始状态,也不可以使用this.state和setState。
constructor
react组件的构造函数在挂载之前被调用。在实现React.Component构造函数时,需要先在添加其他内容前,调用super(props),用来将父组件传来的props绑定到这个类中,使用this.props将会得到。constructor中应当做些初始化的动作,如:初始化state,将事件处理函数绑定到类实例上,但也不要使用setState()。如果没有必要初始化state或绑定方法,则不需要构造constructor,或者把这个组件换成纯函数写法。
getDerivedStateFromProps
getDerivedStateFromProps在组件实例化后,和接受新的props后被调用。他返回一个对象来更新状态,或者返回null表示新的props不需要任何state的更新。
如果是由于父组件的props更改,所带来的重新渲染,也会触发此方法。
(调用setState()不会触发getDerivedStateFromProps()。)
componentWillMount
componentWillMount只在初始化时候被调用一次,可以使用setState方法,会立即更新state,然后接着进行render。(操作state,不会触发再次渲染,建议用constructor代替),如果在这里ajax的话,会导致componentWillMount执行多次,因此,不推荐在这里ajax。
render
根据 state 的值,生成页面需要的虚拟 DOM 结构。注意在render中千万不可使用setState方法,不然马上会引起无限的报错了哈哈。如果其中包含其他的子组件,那么子组件的生命周期才开始进行。
componentDidMount
在子组件也都加载完毕后执行,在RN中就是指组件初始化加载完毕,在react中DOM(真实的dom)渲染完成,此时就可以操作DOM了。可以设置state,会触发再次渲染,组件内部可以通过 ReactDOM.findDOMNode(this)来获取当前组件的节点操作DOM,以及进行ajax数据请求
class App extends Component {
static PropTypes = {
设置props类型阶段
}
static defaultProps = {
设置props默认值阶段
}
constructor(props) {
super(props) 继承传递的值
this.state = { 初始化state
// ...
}
}
componentWillMount() {
预安装阶段
}
render() {
将虚拟DOM结合到真实DOM中
}
componentDidMount() {
可以进行数据请求等操作。可以进行setState
}
}
转自作者:shengqz
链接:https://www.jianshu.com/p/e026dd809f69
更新/渲染:
componentWillReceiveProps(nextProps)
componentWillReceiveProps方法可以比较this.props和nextProps来看是否发生了变化,然后可以进行setState等操作。当组件接收到新的props时会触发该函数,通常可以调用this.setState方法来比较this.props和nextProps的执行状态,完成对state的修改。(注意只要父组件此方法触发,那么子组件也会触发,也就是说父组件更新,子组件也会跟着更新。)
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate 方法在接收了新的props或state后触发,你可以通过返回true或false来控制后面的生命周期流程是否触发。该方法用来拦截新的props或state,然后判断是否更新组件
getDerivedStateFromProps
getDerivedStateFromProps在组件实例化后,和接受新的props后被调用。他返回一个对象来更新状态,或者返回null表示新的props不需要任何state的更新。
如果是由于父组件的props更改,所带来的重新渲染,也会触发此方法。
(调用steState()不会触发getDerivedStateFromProps()。)
componentWillUpdate(nextProps, nextState)
componentWillUpdate在props或state改变或shouldComponentUpdate返回true后触发。不可在其中使用setState。更新之前调用
render
根据diff算法,生成需要更新的虚拟DOM数据
getDerivedStateFromProps(prevProps, prevState)
getDerivedStateFromProps在组件每一次render的时候都会触发,也就是说无论是来自父组件的re-render, 还是组件自身的setState, 都会触发getDerivedStateFromProps这个生命周期。
componentDidUpdate
会等子组件也都更新完后才触发。更新之后调用,可以进行DOM 操作
class App extends Component {
componentWillReceiveProps(nextProps) {
接受更新props阶段,可以使用setState
}
shouldComponentUpdate(nextProps,nextState) {
是否更新props和state阶段,默认为true,代表渲染(更新)
可以在这个阶段对nextProps和当前this.props进行对比,以便确认是否渲染(更新)
}
componentWillUpdate(nextProps, nextState) {
与挂载相似,预安装
}
render() {
将虚拟DOM结合到真实DOM中,纯函数返回值只能有一个顶根元素或null。
}
componentDidUpdate() {
实际渲染(更新)阶段(将DOM添加到HTML中)
}
}
转自作者:shengqz
链接:https://www.jianshu.com/p/e026dd809f69
销毁/卸载:
componentWillUnmount
通常是移除DOM,取消事件绑定,销毁定时器等工作
class App extends Component {
componentWillUnmount() {
可以卸载在componentDidMount的Ajax请求
}
}
转自作者:shengqz
链接:https://www.jianshu.com/p/e026dd809f69
注意:
-
shouldComponentUpdate是做react性能优化最重要的时期
-
如果组件的state是在constructor里依赖props进行初始化的,那么这个state在外部的props的更改的时候,不会触发render,因为constructor只会在初始化时触发,如果说要更新的话,componentWillReceiveProps中再调用setState改变值
-
新版本(16.3)中:static getDerivedStateFromProps(props){}
static静态方法中没有this,因此,不能this.setState修改state的值,如果需要返回修改,直接return -
render中最好只是数据和模板的组合,不应该修改state
如果shouldComponentUpdate返回false,componentWillUpdate,render,componentDidUpdate都不会被调用 -
在接下来的17版本中可能会淘汰componentWillMount,componentWillUpdate,componentWillReceiveProps。