import { useState } from "react";
export default function App() {
console.log("rendered...")
const [count, setCount] = useState(0);
const increaseCount = () => {
setCount(count + 1);
};
const setFourValue = () => {
setCount(4);
};
return (
<div className="App">
<div
style={{ display: "flex", alignItems: "center", columnGap: ".25rem" }}
>
<button onClick={increaseCount}>Increase</button>
<button onClick={setFourValue}>Set 4</button>
<span>{count}</span>
</div>
</div>
);
}
我试图弄清楚组件渲染的时间和方式。我尝试的情况是,我将计数增加到4,现在我的计数值是4。但我点击"Set 4"按钮,我的计数值仍然是4,但仍然是重新渲染的组件。之后,如果再次单击"Set 4"按钮组件,则不会重新渲染。为什么?
在React中,只有当组件中的state
或prop
发生更改时,组件才会重新渲染。
将4
设置为4
并不是一个更改。
React足够聪明,不会不必要地重新渲染。
要补充Barry的答案,当您第一次用setFourValue
将计数设置为4
,然后用increaseCount
将计数增加到4
时,它实际上不是4。控制台记录计数,您会看到它实际上是3
,尽管它在屏幕上显示4
。
increaseCount
函数出现问题。使用状态属性以前的值更新状态属性时,必须使用回调参数。这是由于状态更新的异步性质。(请参见https://reactjs.org/docs/state-and-lifecycle.html#state-更新可能是异步的)
const increaseCount = () => {
setCount((count) => (count + 1));
};
这可能是@Tim van Dam所说的count
为3而不是4的原因。
在解释当更新的状态值取决于以前的状态值时,setState的回调模式应该如何被首选时,这里的大多数答案都是正确的。但问题的一部分仍有待解决
但我点击"Set 4"按钮,我的计数值仍然是4,但仍然是重新渲染的组件。
我创建了这个sandbox
,这确实发生了。
如果我们从increaseCount
开始执行setCount(4)
,然后从setFourValue
开始执行,则两者都会触发重新应答。
答案就在这里
请注意,React可能仍需要在退出之前再次渲染该特定组件。这不应该是一个问题,因为React不会不必要地"深入"到树中。
React确实没有深入到树中,您可以通过取消对<Child>
的注释来进行检查。它不会深入到树中,因为即使<App>
重新发送,<Child>
也不会重新发送。