export default function Comp() {
const [state, setState] = useState(true); // new line added
let rand = Math.random();
useEffect(() => {
console.log("Hello Word");
}, [rand]);
// notice that the click handler has changed
return (
<button onClick={() => setState(!state)}>
New value
</button>
);
}
3条答案
按热度按时间xfb7svmp1#
任何变量都可以进入依赖数组,不管是不是
state
,只要它在数组中并且改变了,useEffect
的回调函数就会被重新执行.现在,
useEffect
是如何注意到这个变化的呢?嗯,每当组件呈现时,它都会执行diff。只有state
与setState
的变化才能触发呈现(这里不讨论呈现,因为这里有父组件呈现)。如果你已经理解了这个机制,你可以停在这里,用React构建你的神奇产品:)。否则,继续阅读。我编了一个例子来解释更多。
假设我们有下面的组件。我们应该在组件第一次渲染时,以及每次
rand
更改时,在控制台中记录Hello Word
。单击button
会更改rand
,但我们不会有新的日志,因为没有state
更改时,没有任何重新渲染,所以useEffect
没有做diff。所以它不知道这个变化。让我们对这个组件做一些修改,如下所示。现在每次点击按钮,组件都会重新呈现,因为我们用
setState
设置了state
,在重新呈现时,如果rand
的值与前一个值不同,我们将得到一个新的日志。x6h2sr282#
每次重新呈现组件时,都会计算
Math.random
方法,因此它将导致useEffect
再次运行(rand
已更改的情况除外)。相反,如果它只是一个常量,它将不会重新运行
useEffect
。mm5n2pyu3#
如果你在
useEffect
中使用console.log("hello")
,你会发现你只看到两个控制台显示“hello”(因为componentWillMount和componentDidMount)。这意味着,你的组件只有在状态变量的值改变或者传递给它的属性改变时才会重新呈现(当然传递的属性必须是状态,否则它不会重新呈现)。结论:只有组件中state或props的值发生更改时,才会重新呈现组件。