React Strict Mode

React StrictMode

触发时机: 开发模式, 并且调用 StrictMode

执行时机

严格模式的运行是不会有 console.log 的输出的。输出的 view,都是第二次运行后的结果。据实验,方法组件是第二次是严格模式的运行(因为第二次的 console.log 没有输出),类组件则是第一次是严格模式(因为,第一次的 console.log 没有输出)。
严格模式额外执行的函数是那些不应该有额外副作用的函数,值的是发生在 render 阶段的。

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  //<App />,
  document.getElementById('root')
);

作用

  • 识别不安全的生命周期
  • 关于使用过时字符串 ref API 的警告
  • 关于使用废弃的 findDOMNode 方法的警告
  • 检测意外的副作用
  • 检测过时的 context API

检测意外的副作用

这些方法会被调用两次

  • constructor
  • componentWillReceiveProps
  • componentWillUpdate
  • getDerivedStateFromProps
  • shouldComponentUpdate
  • render
  • setState 更新函数(第一个参数)
  • FunctionalComponent 会被执行两遍
    • React.useMemo, React.useState, React.useCallback, 这些 hook 函数也会被执行两次
      如果你有些代码确定只能执行一遍,一定要考虑严格模式下会执行两遍这个事情,可以通过 useref 来进行判断或者自行加逻辑进行判断。
      还有一个很奇怪的,React.useState,返回的 [val,setVal],StrictMode 的setVal会使得组件重新渲染,但是并没有改变 val,的值。
      这边遇到的坑是,在写EditTree的时候,我首先将 inlineTools 保存到TreeData的每一个节点,并保证了唯一性,也就是有了就不赋值了,这个时候发现 inlineTools 的点击事件并没有引起页面正确的响应,后来分析原因就是因为,click 事件里面所使用的setVal来自于 StrictMode 下的返回。它虽然能引起页面的刷新,不过那个页面是 StrictMode 下的页面,并不是我们可见的那个页面。

方法组件中的注意点

  • React.useState(initial|func), 这个 initial|func 会被执行两遍。例如React.useState(()=>++t),t 的值会是 2,而不是 1。因为约定 React.useState,里面的参数是不能有副作用的。
  • 依据此特性,这些 hook 也会执行两遍,React.useRef,React.useDispatch

rc-trigger 里面就有个 bug

https://github.com/react-component/trigger/issues/264

posted @ 2021-05-23 22:52  kongshu  阅读(273)  评论(0编辑  收藏  举报