我正在使用以下虛擬組件進行一些測驗,在執行時(在控制臺中)我得到以下結果:
Rendering: 0
Triggered: 0
Rendering: 4
Triggered: 4
Rendering: 4
我很難理解為什么。
第一次渲染:
- 設定
index為0。 - 運行 useEffect
undefined不是0 - useEffect 請求設定
index為4
第二次渲染:
index是4- 為什么useEffect body又被執行了?
第三次渲染:
- 為什么會有重新渲染?
我期望的是:
Rendering: 0
Triggered: 0
Rendering: 4
我是否跳過了一些非常明顯的東西?你能幫我理解它是如何在幕后作業的嗎?
const Example = React.memo(() => {
const [index, setIndex] = React.useState(0)
console.log('Rendering: ', index)
React.useEffect(() => {
console.log('Triggered: ', index)
setIndex(4)
}, [index])
return <h1>{index}</h1>
})
ReactDOM.render(<Example />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
uj5u.com熱心網友回復:
重新渲染的數量實際上是正確的。讓我們分析一下會發生什么:
- 渲染 0 - 這是在安裝第一次渲染時(在這種狀態下,每個
useEffect都自動運行)
- 觸發 0 - 這是初始觸發
useEffect
- 渲染 4 - 此重新渲染是因為您將新狀態設定
index為4
- 觸發 4 - 這是因為您
index從 0 更改為 4而觸發
- 渲染 4 - 這是因為狀態從
4to更改為運行4(即使值相同,它也會觸發組件重新渲染,因為 React 不知道您是否設定了相同的狀態,它需要再次運行)。在此重新渲染中, useEffect未運行,因為index再次為 4。
基本原理
如果組件在任何時候發生任何變化,例如useState useContext, customHook,則該組件將需要重新渲染。如果父組件重新渲染也會發生這種情況,即使您的組件沒有任何更改,子組件也會重新渲染。
其他重新渲染提示和資訊
為了防止父組件發生不必要的子組件重新渲染,您可以使用React.memo,如果 props 更改,這將重新渲染您的組件,但不會阻止您的組件在 state 或上述任何鉤子發生更改時重新渲染。
如果這看起來是多余的,聽起來很像,但有必要讓 react 確保它具有最新狀態。像這樣運行 JS 比擁有一些檢查更改的狀態記憶體要快,而且它對開發人員更透明(以及VDOM的創建方式)
uj5u.com熱心網友回復:
無法達到預期的輸出。
useEffect 在組件掛載時渲染,并且在狀態更改(索引)時每次重新渲染時渲染。
const Example = () => {
const [index, setIndex] = React.useState(0)
console.log('Rendering: ', index)
React.useEffect(() => {
console.log('Triggered: ', index)
setIndex(4)
}, [index])
return <h1>{index}</h1>
}
輸出:
- 渲染:0 => 組件第一次掛載時,該時間索引為 0
- 觸發:0 => 掛載 useEffect 觸發,狀態更新(0 到 4)
- 渲染:4 => 組件重新渲染,因為狀態已從(0 變為 4)
- 已觸發:4 => useEffect 重新觸發,因為狀態已更改(0 到 4)
- 渲染:4 => Componet 重新渲染,因為要檢查狀態是否已更改(4 到 4,確認沒有任何變化)
uj5u.com熱心網友回復:
useEffect 的作業方式是它只在頁面組件渲染后運行。
希望這能幫助你理解。
第一個渲染索引為 0。
Rendering: 0
它觸發了useEffect。
Triggered: 0
索引在 useEffect 中更新,但不在組件中。然后 render 將索引更新為 4。
Rendering: 4
useEffect 運行,因為索引已更改。
Triggered: 4
組件再次渲染,但索引仍為 4,因此 useEffect 不會再次運行。
Rendering: 4
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/415570.html
標籤:
