我面临着多次重新渲染,因此为了找到问题,我注释了每一行代码,最后找到了导致重新渲染的常量定义:
const MyComponent = () => {
console.log('render') // logs 4 times
const myRef = useRef(null)
return <h1>hello</h1>
}
const MyComponent = () => {
console.log('render') // logs 2 times
return <h1>hello</h1>
}
我知道严格模式会渲染组件 2 次。但是,为什么只定义myRef
常量导致进一步重新渲染 2 次?
我刚刚尝试React.memo
作为评论,但它仍然呈现 4 次:
export default React.memo(MyComponent)
好的,我刚刚在应用程序中使用相同的代码进行了测试.js它只记录了 2 次。因此,这似乎是父组件问题。但我的问题是为什么在子组件中没有任何导致渲染额外 2 次只是定义变量?
正如你和 React 文档所说:
严格模式无法自动为您检测副作用,但它 可以通过使它们更具确定性来帮助您发现它们。 这是通过有意双重调用以下函数来完成的:
- 类组件构造函数、呈现器和 shouldComponentUpdate 方法
- 类组件静态 getDerivedStateFromProps 方法
- 函数组件体
- 状态更新程序函数(setState 的第一个参数(
- 传递给 useState、useMemo 或 useReducer 的函数
来源: https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects
它不包括useRef
但它实际上应该在此列表中,因为它使用与useState
相同的底层机制
React.memo
在这里无济于事,因为导致重新渲染的是React.StrictMode
检查副作用和其他东西的特殊机制,因此它忽略了memo
和类似的技术。
有趣的是,如果您在 Parent 组件中添加useRef
,它将调用函数体 2 次,但它的子项(如果它们不使用useRef
(将只调用一次。
所有这些东西只适用于开发模式,所以在生产中不会有任何有意的双重调用和其他事情,但它们仍然可能无意中发生。