[英]React setState hook not working with useEffect
我有以下代碼。 這個想法是為模擬組件創建一個簡單的加載
const [loading, setLoading] = useState(false)
function mockLoading () {
setLoading(true)
console.log('1', loading)
setTimeout(() => {
setLoading(false)
console.log('2', loading)
}, 3000)
}
useEffect(() => {
mockLoading()
}, []);
但由於某種原因,setLoading 不起作用。 Console.log 1 和 2 都是假的
有幾件事。 一個問題是,當您設置 state 時,state 不會立即更新。 因此,您的第一個 console.log 將看到舊的 state。 不僅如此,當你的效果被調用和mockLoading
被調用時,它只會看到它被調用時存在的 state 的實例。 因此mockLoading
永遠不會看到對變量的任何更改。 這就是效果具有依賴性的原因。 這樣,當依賴項更新時,您會看到它。 但考慮到您的代碼的結構,我認為這里沒有依賴項會有所幫助。 我對您的最終目標不是 100% 清楚,但是要根據您提交的代碼完成您想要的,您需要使用useRef
而不是useState
。 useRef
給你一個 object ,它的值總是最新的。 看:
const loadingRef = useRef(false)
function mockLoading () {
loadingRef.current = true;
console.log('1', loadingRef.current)
setTimeout(() => {
loadingRef.current = false;
console.log('2', loadingRef.current)
}, 3000)
}
useEffect(() => {
mockLoading()
}, []);
除非您絕對需要,否則通常不贊成使用 refs。 嘗試重構您的代碼以依賴於loading
您的useEffect
調用。 但請記住,如果您的mockLoading
在調用時總是更新loading
,您可能會以無限循環告終。 如果尚未設置為您想要的值,請嘗試僅更新loading
。 如果您的最終目標是在 3 秒后更新loading
,請嘗試以下操作:
const [loading,setLoading] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoading(true);
},3000);
},[]);
return <span>{loading ? 'Loading is true!' : 'Loading is false!'}</span>;
如果你想在不渲染的情況下檢查加載的值,那么你需要另一個依賴於loading
的useEffect
:
const [loading,setLoading] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoading(true);
},3000);
},[]);
useEffect(() => {
console.log(loading);
},[loading]);
return <span>{loading ? 'Loading is true!' : 'Loading is false!'}</span>;
希望這可以幫助。
在useEffect
聲明您的handler
並在外部登錄
const [loading, setLoading] = useState(false)
useEffect(() => {
function mockLoading () {
setLoading(true)
console.log('1', loading)
setTimeout(() => {
setLoading(false)
console.log('2', loading)
}, 3000)
}
mockLoading()
}, []);
console.log(loading)
此外,您應該在unmount
時清除timeout
useEffect(() =>{
const timeout = setTimeout(() =>{}, 0)
return clearTimeout(timeout)
},[])
在 React 中設置 state 是異步的,因此您不會在創建 state 后立即看到更改。 要跟蹤 state 更改,您需要使用效果掛鈎:
const [loading, setLoading] = useState(false);
function mockLoading() {
setLoading(true);
console.log("1", loading);
setTimeout(() => {
setLoading(false);
console.log("2", loading);
}, 3000);
}
useEffect(() => {
mockLoading();
}, []);
// Display the current loading state
useEffect(() => {
console.log("loading", loading);
}, [loading]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.