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

React 的生命周期有哪些

Explain the React component lifecycle and its methods

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

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

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

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

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

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

  • Mounting: constructor getDerivedStateFromPropsrender 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.