DrillLab
第 60 / 105 道60 / 105 · #323

React 的生命周期有哪些

Explain the React component lifecycle and its methods

先自己答,再往下看Answer it yourself first

一句话:三个阶段 ——挂载、更新、卸载。

  • 挂载:constructor →getDerivedStateFromProps →render →componentDidMount(DOM 已经有了,发请求、订阅、操作 DOM 都在这)
  • 更新:getDerivedStateFromProps →shouldComponentUpdate(返回 false 就跳过渲染)→render →getSnapshotBeforeUpdate →componentDidUpdate(这里改 state 必须加条件,否则死循环)
  • 卸载:componentWillUnmount(清定时器、解绑监听、取消请求)
  • 出错:getDerivedStateFromError +componentDidCatch(错误边界,见 #333)

三个被废弃的要知道:componentWillMount、componentWillReceiveProps、componentWillUpdate。原因是 Fiber 的 render 阶段可能被中断和重跑,这几个方法可能被调用多次,放在里面的副作用会重复执行。能说出这个原因很加分。

会追问:「请求为什么不放componentWillMount?」—— 除了上面的原因,它在 SSR 时也会执行,而且并不会更早拿到数据(请求是异步的,反正要等)。

In one line: three phases — mounting, updating, unmounting.

  • Mounting: constructor → getDerivedStateFromProps → render → componentDidMount (the DOM exists now, so fetching, subscribing and DOM work all belong here)
  • Updating: getDerivedStateFromProps → shouldComponentUpdate (return false to skip the render) → render → getSnapshotBeforeUpdate → componentDidUpdate (setting state here needs a condition, or you get an infinite loop)
  • Unmounting: componentWillUnmount (clear timers, detach listeners, cancel requests)
  • On error: getDerivedStateFromError + componentDidCatch (error boundaries, see #333)

Know the three that were deprecated: componentWillMount, componentWillReceiveProps, componentWillUpdate. The reason is that Fiber can interrupt and re-run the render phase, so these could fire more than once and any side effect inside them would run twice. Giving that reason earns real credit.

Follow-up: “Why not fetch in componentWillMount?” — besides the reason above, it also runs during SSR, and it does not get the data any sooner: the request is async, so you wait either way.