首先,我無法弄清楚這段代碼中的問題。但可能這個問題在這里有立足之地。
據我所知,問題可能是單擊按鈕后計數器值沒有更新。警報顯示單擊按鈕時的值,盡管在 2.5 秒的延遲期間我單擊并增加了計數器的值。
我是對的,如果是這樣,應該在這里修復或添加什么?
import React, { useState } from 'react'
function Root() {
const [count, setCount] = useState(0)
function handleAlertClick() {
setTimeout(() => {
alert(`You clicked ${count} times`)
}, 2500)
}
return (
<Container>
<Column>
<h4>Closures</h4>
<p>You clicked {count} times</p>
<button type="button" onClick={() => setCount(counter => counter 1)}>
Click me
</button>
<button type="button" onClick={handleAlertClick}>
Show alert
</button>
</Column>
</Container>
)
}
export default Root
uj5u.com熱心網友回復:
問題
當setTimeout被呼叫時,它的回呼函式會關閉組件count當前渲染中 的當前值Root。
在計時器到期之前,如果您更新count,則會導致重新渲染組件,但 的回呼函式setTimeout仍會看到呼叫時生效的值setTimeout。這是由代碼中的閉包引起的問題的要點。
Root組件的每個渲染都有自己的狀態、道具、組件內部定義的本地函式;簡而言之,組件的每個渲染都與它之前的渲染分開。
狀態在組件的特定渲染中是恒定的;組件在重新渲染之前無法看到更新的狀態。前一次渲染中設定的任何計時器都會看到它關閉的值;它看不到更新的狀態。
解決方案
您可以使用useRef鉤子來擺脫由于關閉而導致的問題。
每次Root重新渲染組件時,您都可以更新 ref 。這允許我們count在 ref 中保存最新的值。
一旦你有一個 ref,而不是傳遞count給alert,傳遞 ref。這可確保警報始終顯示 的最新值count。
function Root() {
const [count, setCount] = React.useState(0)
const countRef = React.useRef(count);
// assign the latest value of "count" to "countRef"
countRef.current = count;
function handleAlertClick() {
setTimeout(() => {
alert(`You clicked ${countRef.current} times`)
}, 2500)
}
return (
<div>
<h4>Closures</h4>
<p>You clicked {count} times</p>
<button type="button" onClick={() => setCount(counter => counter 1)}>
Click me
</button>
<button type="button" onClick={handleAlertClick}>
Show alert
</button>
</div>
)
}
ReactDOM.render(<Root/>, document.getElementById("root"));
<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>
<div id="root"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/344625.html
標籤:javascript 反应 异步 设置超时
