[英]Callback doesn't receive the updated version of state even when it fires well after state changes
我正在使用功能組件。 我知道setColor
會異步更改color
的值。 但是,我的回調 function 沒有收到color
(藍色)的更新版本,即使它在color
更新后執行得很好。 這是我的代碼的抽象版本:
let [color, setColor] = useState("red");
useEffect(() => {
setColor("blue");
setTimeout(() => {
console.log(color);
}, 5000)
}, []);
(這是一個沙箱: https://codesandbox.io/s/falling-cherry-17ip2?file=/src/App.js )
我唯一的猜測是setColor
function 幾乎創建了一個新的color
變量,並且console.log
被引用舊color
卡住了。
故障排除
我知道當 state 發生變化時,輔助useEffect
有可能執行我的回調。 但是,這很不方便,因為我正處於復雜邏輯的中間,我只希望回調在某些條件下執行。
我也知道useRef
變量會立即更新,因此這是一個替代方案。
盡管如此,問題仍然存在:為什么沒有記錄color
的更新值?我可以在主要useEffect
中做些什么來訪問最新版本的color
state?
setColor
更改 state。let [color, setColor] = useState("red");
color
的當前 state 分配給color
變量。setTimeout
的箭頭 function 運行。 這已經關閉了分配舊state 的先前color
變量。這是一段記錄不同時間color
state 值的片段,還顯示了在 useEffect 返回時清理的效果。 它只是用來說明昆汀在他們的回答中列出的時間表。
const App = ()=>{ const [color, setColor] = React.useState("red"); console.log('outside: ', color); React.useEffect(() => { setColor("blue"); console.log('inside: ', color); setTimeout(() => { console.log('inside-timed: ', color); }, 5000) // the cleaned-up timer won't fire const timer = setTimeout(() => { console.log('timer: ', color); }, 5000) return (clearTimeout(timer)); },[]) return ( <div style={{backgroundColor: color, width: '40px', height: '40px'}} ></div> ) } ReactDOM.render( <App />, document.getElementById("react") );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="react"></div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.