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.useMemo, React.useState, React.useCallback, 这些 hook 函数也会被执行两次
方法组件中的注意点
- React.useState(initial|func), 这个 initial|func 会被执行两遍。例如
React.useState(()=>++t)
,t 的值会是 2,而不是 1。因为约定 React.useState,里面的参数是不能有副作用的。 - 依据此特性,这些 hook 也会执行两遍,React.useRef,React.useDispatch