Skip to content

React 类组件的生命周期现在怎么答? ​

函数组件没有这套方法名,副作用在 useEffect 里。类组件要记住三条线:挂载、更新、卸载。数据请求放在挂载后,退订放在卸载,渲染函数本身保持纯净。

原理 ​

挂载:constructor 初始化状态,render 描述 UI,然后提交 DOM,componentDidMount 里可以请求数据和订阅。

更新:新的 props 或 setState 之后再次 render,提交后进入 componentDidUpdate。在这里根据 props 变化发请求时,要比较前后 props,并在下一次更新或卸载时忽略过期结果。

卸载:componentWillUnmount 里取消订阅、定时器和未完成的请求。

getDerivedStateFromProps 和 getSnapshotBeforeUpdate 很少需要。前者容易把 props 抄进 state,造成两份数据。派生值直接在 render 里算。

曾经的 componentWillMount、componentWillReceiveProps、componentWillUpdate 在并发渲染下可能执行多次,不要再用。

追问 ​

为什么请求不放在 constructor 或 render?

render 可能重复执行,必须是纯的。构造函数里发请求会在服务端渲染时产生副作用,也更难取消。挂载完成后,DOM 已经在,订阅也有了对称的卸载点。

和 Hooks 怎么对应?

useEffect 覆盖挂载后、更新后和卸载前的清理。useLayoutEffect 更接近提交后、绘制前的 componentDidMount 布局测量。见 React Hooks。

易错点 ​

  • 在 componentWillUnmount 里 setState。组件已经走了,这次更新没有意义,还会有警告。
  • componentDidUpdate 里无条件 setState,造成死循环。
  • 把 getDerivedStateFromProps 当成「props 一变就同步进 state」的默认手段。

相关 ​