簡體   English   中英

反應 setState 鈎子不適用於 useEffect

[英]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>;

如果你想在不渲染的情況下檢查加載的值,那么你需要另一個依賴於loadinguseEffect

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM