在我的React组件中,我希望只有当某些状态发生变化时才触发某些操作。我将状态初始化为一个默认值,并将其放入钩子的依赖数组中。在会话期间,我根本不会改变这种状态。但是,React在组件首次挂载后仍然会运行useEffect钩子。
我想知道它为什么会这样。有没有一种优雅的方式(或者最佳实践是什么)来实现这一点?谢谢你的帮助!
代码如下所示:
import React from 'react';
export function App(props) {
const [testString, setTestString] = React.useState('abc');
console.log(testString);
React.useEffect(() => {
console.log('******* I am not supposed to log here !!!')
}, [testString]);
return (
<div className='App'>
<h1>Hello React.</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
也可在www.example.com上获得playcode.io:https://playcode.io/1458690
3条答案
按热度按时间db2dz4w81#
根据documentation for
useEffect
:当你的组件第一次被添加到DOM时,React会运行你的设置函数。在每次使用更改的依赖项重新渲染之后,React将首先使用旧值运行cleanup函数(如果您提供了它),然后使用新值运行setup函数。
可以使用ref存储组件是否已装载,以区分初始渲染和更新。
参见:Equivalent to componentDidUpdate using React hooks。
cunj1qz12#
监听组件何时在其他useEffect之前挂载(useEffect with empty dependency array)(它们按顺序运行)并在那里设置一个标志...我不知道它有多优雅,但它很有效:
0pizxfdo3#
useEffect钩子的默认行为是,它总是在组件第一次挂载时被调用。无论是否包含依赖关系数组,情况都是如此。这就是为什么你得到了你的问题中描述的行为。
如果包含了依赖数组,那么只要该数组中的某个依赖项发生更改,就会调用useEffect。如果不包含依赖项数组,则useEffect将仅在组件首次装入时调用一次。
您可以使用useRef钩子来创建一个变量,比如
const firstRender = useRef()
,它跟踪是否是第一次渲染。在useEffect内部检查firstRender.current
是否为true,如果是,则将其设置为false并返回useEffect,而不运行任何其他代码。如果firstRender.current
为false,则执行您希望在useEffect中执行的操作。