constructor()
加载的时候调用一次,可以初始化state
getDefaultProps()
设置默认的props,也可以用dufaultProps设置组件的默认属性。
getInitialState()
初始化state,可以直接在constructor中定义this.state
componentWillMount()
组件加载时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state
render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行
componentDidMount()
组件渲染之后调用,只调用一次
componentWillReceivePorps(nextProps)
组件加载时不调用,组件接受新的props时调用
shouldComponentUpdate(nextProps, nextState)
react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候
componentWillUpdata(nextProps, nextState)
组件加载时不调用,只有在组件将要更新时才调用,此时可以修改state
render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行
componentDidUpdate()
组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。prevProps和prevState这两个参数指的是组件更新前的props和state。
componentWillUnmount()
组件将要卸载时调用,一些事件监听和定时器需要在此时清除。
如果一个很大,层级很深的组件,react渲染它需要几十甚至几百毫秒,在这期间,react会一直占用浏览器主线程,任何其他的操作(包括用户的点击,鼠标移动等操作)都无法执行。好似一个潜水员,当它一头扎进水里,就要往最底层一直游,直到找到最底层的组件,然后他再上岸。在这期间,岸上发生的任何事,都不能对他进行干扰,如果有更重要的事情需要他去做(如用户操作),也必须得等他上岸,Fiber就是为了解决这个问题。
Fiber的react组件将分为两个时期,以render()为分界线。render之前的生命周期是可以被打断的,每隔一段时间它会跳出当前渲染进程,去确定是否有其他更重要的任务。此过程,React 在 workingProgressTree (并不是真实的virtualDomTree)上复用 current 上的 Fiber 数据结构来异步地(通过requestIdleCallback)来构建新的 tree,标记出需要更新的节点,放入队列中等待第二阶段一次性全部更新到dom中,第二个阶段是不可以打断的。
第一个阶段如果被打断,所有之前的操作都要重新进行一遍,所以,第一个阶段的所有生命周期函数都是有可能被多次调用的,那么我们最好就得保证第一阶段的生命周期每一次执行的结果都是一样的,否则就会有问题,因此,最好都是纯函数,所以删除了render()之前的那些声明函数,引入了静态函数getDerivedStateFromProps。
static getDerivedStateFromProps(nextProps, prevState) //用来替换componentWillReceiveProps
getSnapshotBeforeUpdate(prevProps, prevState) // 获取render之前的dom状态,根据数据长度计算高度等。。
参考:https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
https://segmentfault.com/a/1190000016617400