Xen*_*mar 10 reactjs react-hooks
I am trying to figure out, when useEffect causes a rerender. I am very surprised by the result of the following example:
https://codesandbox.io/embed/romantic-sun-j5i4m
function useCounter(arr = [1, 2, 3]) {
const [counter, setCount] = useState(0);
useEffect(() => {
for (const i of arr) {
setCount(i);
console.log(counter);
}
}, [arr]);
}
function App() {
useCounter();
console.log("render");
return <div className="App" />;
}
Run Code Online (Sandbox Code Playgroud)
The result of this example is as follows:
My confusion stems from two things: I don't know why:
I would be super happy if someone could clarify. Thanks!
我将尽力解释(或逐步进行)正在发生的事情。我还在第7点和第10点做两个假设。
useEffect
安装后称为。useEffect
将“保存”初始状态,因此counter
每次在其内部引用时将为0。setCount
都会调用以更新计数,并且控制台日志会记录计数器,根据“存储的”版本,该计数器为0。因此,数字0在控制台中记录了3次。因为状态已更改(0-> 1、1-> 2、2-> 3),所以React集就像一个标志或告诉自己要记住要重新渲染的东西。useEffect
,而是等到useEffect
完成之后再渲染。useEffect
完成,React就会记住的状态counter
在其执行过程中已更改,因此它将重新呈现该App。useCounter
再次被调用。请注意,这里没有参数传递给useCounter
自定义钩子。
假设: 我自己也不知道这一点,但是我认为默认参数似乎又被创建了,或者至少以某种方式使React认为它是新的。因此,由于将arr
视为新的,因此该useEffect
钩子将再次运行。这是我可以useEffect
再次解释运行的唯一原因。useEffect
,的counter
值将为3。因此,控制台日志将记录3号为预期的三倍。useEffect
第二次运行后,React发现计数器在执行过程中发生了变化(3-> 1,1-> 2,2-> 3),因此该应用将重新渲染,从而导致第三个“渲染”日志。useCounter
从App的角度来看,挂钩的内部状态在此渲染与前一个渲染之间没有发生变化,所以它不会在其中执行代码,因此useEffect
不会被第三次调用。因此,应用程序的第一个渲染将始终运行挂钩代码。应用程序第二次看到钩子的内部状态counter
从0 更改为3,因此决定重新运行它,第三次应用程序看到钩子的内部状态为3并且仍然为3,因此决定不重新执行-运行。这是我想出的让钩子不再运行的最好原因。您可以在挂钩本身中放入一个日志,以查看它实际上并没有第三次运行。这就是我所看到的,我希望这可以使它更加清晰。
归档时间: |
|
查看次数: |
6598 次 |
最近记录: |