亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

React:如何避免使用始終返回相同值但更改其內部狀態的鉤子重新渲染組件

React:如何避免使用始終返回相同值但更改其內部狀態的鉤子重新渲染組件

慕村225694 2023-07-20 16:38:22
想象一下這個鉤子每秒都會改變他的值,如果隨機值是 5 的倍數則返回 true,否則返回 false。我該怎么做才能停止每秒重新渲染?PS:我嘗試使用 useMemo 和 useRef 始終返回相同的對象,但它仍在重新渲染。請幫忙const useRandomIs5x = () => {  const [state, setState] = useState(0);  useEffect(() => {    const t0 = setInterval(() => {      setState(getRandomValue())    }, 1000)    return () => clearInterval(to)  }, [])  return state % 5 === 0;}const Root = () => {  const bool = useRandomIs5x();  console.log("I'm re-rendering every second", bool)  return <div>test</div>}
查看完整描述

4 回答

?
梵蒂岡之花

TA貢獻1900條經驗 獲得超5個贊

我相信如果沒有一些解決方法,這幾乎是不可能實現的。要調用setState或不調用,我們必須訪問當前狀態值。如果我們傳入state依賴數組,這是可能的。但隨后,該間隔將每秒重新創建。


也可以使用 refs 來實現,但是目前還沒有正確的方法來監聽ref 的更改。


更新:看起來它可以很好地用作useRef以前的數據持有者。感謝安豪2。


const { useEffect, useState, useRef } = React;


const useRandomIs5x = () => {

  const [state, setState] = useState(true);

  const ref = useRef(null);

  

  useEffect(() => {

    const t0 = setInterval(() => {

      const value = Math.floor(Math.random() * 5) % 5 === 0;

      if (value === ref.current) return;

      ref.current = value;

      setState(value);

    }, 1000);


    return () => clearInterval(t0);

  }, []);


  return state;

}


const Root = () => {

  const bool = useRandomIs5x();

  console.log('re-render!', bool);

  return <div>test</div>

}


ReactDOM.render(<Root />, document.getElementById("root"));

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>

<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>


<div id="root"></div>


查看完整回答
反對 回復 2023-07-20
?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

我可以使用這個庫react-hooks-in-callback來解決這個問題,?將鉤子與組件隔離。


查看完整回答
反對 回復 2023-07-20
?
料青山看我應如是

TA貢獻1772條經驗 獲得超8個贊

您可能需要采取一些不同的方法。你不需要隨機值,你想要它是否能被 5 整除。所以這就是狀態并從鉤子返回的內容。隨機值只能作為參考。所以嘗試這樣的事情(代碼未經測試,但應該給你一個總體思路):


const useRandomIs5x = () => {

    const [divisibleBy5, setDivisibleBy5] = useState(true);

    const randomValue = useRef(0);


    useEffect(() => {

        const t0 = setInterval(() => {

            // Set the new random value into a ref so as to not cause re-render

            randomValue.current = getRandomValue();


            const randIsDivisibleBy5 = randomValue.current % 5 === 0;


            // Only if it changes do we update the boolean state and trigger re-render

            if (randIsDivisibleBy5 !== divisibleBy5) {

                setDivisibleBy5(randIsDivisibleBy5);

            }

        }, 1000);

        

        return () => clearInterval(to);

    }, []);


    // Return the boolean state value instead

    return divisibleBy5;

}


查看完整回答
反對 回復 2023-07-20
?
臨摹微笑

TA貢獻1982條經驗 獲得超2個贊

我們最好更改狀態來存儲 is5x 而不是值。一種可能的解決方案是使用 useRef 來檢查我們是否應該每秒更新該值。然后,同步 useRef 和狀態值。


const useRandomIs5x = () => {

  const [state, setState] = useState(false);

  const prevIs5x = useRef(false);

  useEffect(() => {

    const t0 = setInterval(() => {

      const is5x = getRandomValue() % 5 === 0;

      const isDiff = is5x !== prevIs5x.current;

      prevIs5x.current = is5x;

      if (isDiff) {

        setState((prevState) => !prevState);

      }

    }, 1000);

    return () => clearInterval(t0);

  }, []);

  return state;

};


查看完整回答
反對 回復 2023-07-20
  • 4 回答
  • 0 關注
  • 214 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號