我寫了一個簡單的 react 來測驗 React 是如何渲染的:
import ReactDOM from 'react-dom';
import React, { useState, useEffect } from 'react';
const App = (props) => {
// State
const [trackIndex, setTrackIndex] = useState(1);
const [trackProgress, setTrackProgress] = useState(0);
const clickHandler = () =>{
setTrackIndex((trackIndex)=>trackIndex 1)
}
useEffect(() => {
console.log("effect; trackIndex=",trackIndex)
console.log("effect; trackProgress=",trackProgress)
if(trackIndex<5){
console.log("set trackProgress")
setTrackProgress(trackIndex)
}
});
console.log("render")
return (
<div>
<p>{trackIndex}</p>
<p>{trackProgress}</p>
<button onClick={clickHandler}>Click me</button>
</div>
);
};
ReactDOM.render(
<App />,
document.getElementById('root')
);
以下是控制臺輸出:
render
effect; trackIndex= 1
effect; trackProgress= 0
set trackProgress
render
effect; trackIndex= 1
effect; trackProgress= 1
set trackProgress
render
在我單擊按鈕之前,React 似乎渲染了 3 次。最后的渲染真的讓我感到困惑。誰能向我解釋為什么會發生這種渲染以及為什么在這種渲染后沒有效果?先感謝您
uj5u.com熱心網友回復:
似乎您在組件的初始渲染中useEffect設定了狀態setTrackProgress。這是因為trackIndex從1低于 5 的開始。(由 看到if(trackIndex<5)) 注意您沒有提供陣列依賴useEffect作為第二個引數。根據react-documentation這意味著效果只會在組件的第一次初始渲染后發生一次。
另外,我建議添加useCallback到您clickHandler的以防止為每個渲染重新定義函式。(根據反應檔案)
uj5u.com熱心網友回復:
你實際上是在制造一個無限回圈,但 React 拯救了你。第一個render日志是初始渲染,然后useEffect執行并且您的組件重新渲染,導致第二個render日志和第一個effect; ...日志。現在useEffect執行第二個。但是, 的值trackIndex沒有改變,所以你的 if 陳述句將評估為真并trackProgress以相同的狀態/值(1)更新。這會導致另一個重新渲染和第三個render日志。現在,你會認為第三個useEffect會被執行,但 React 足夠聰明,可以知道狀態何時沒有改變,因此不會執行useEffect.
useEffect如上所述向您添加依賴項。那會解決你的問題。
useEffect(
...
, [trackIndex])
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/365186.html
標籤:javascript 反应 渲染
下一篇:切換翻轉卡片
