搜尋

首頁  >  問答  >  主體

在第三方函式庫中呼叫狀態設定器時如何防止狀態重置

我正在嘗試將 React 類別元件轉換為 React 函數元件。

有一個 onChange 函數,可以在元件內部和外部呼叫。 當呼叫函數元件函數時,useState 掛鉤會取得初始值。當我使用舊的類組件方式時,一切正常。為什麼會出現這種情況,如何解決這個問題?

const MyInput = (props) => {
  const { someLib, ...otherProps } = props;
  const [test, setTest] = useState(1); // console show 1,2,3, etc
            
  useEffect(() => {
    someLib && someLib.addCallback(onChange);
  }, []);

  const onChange = (event) => { 
    setTest(test + 1) // this function can called inside MyInput, and from someLib, 
                      // when it called from someLib, 'test' is reset, but in class component everything good 
  }
}

P粉835428659P粉835428659448 天前640

全部回覆(1)我來回復

  • P粉514001887

    P粉5140018872023-09-11 22:01:16

    問題是 onChange 是一個過時的閉包。您需要做的是讓 onChange 看起來像這樣:

    const onChange = (event) => {
        setTest(oldTest => oldTest +1)
    }
    

    或者,您可以將 test 新增到 useEffect 中的依賴項陣列中,但請確保進行清理。 (無論如何你都應該這樣做,但現在更重要)

    useEffect(() => {
        someLib && someLib.addCallback(onChange);
    
        return () => {
            someLib.removeCallback(onChange);
        }
    }, [someLib, test]);
    

    從技術上講,如果您正在執行後一種方法,您需要useCallback

    #
    const onChange = useCallback((event) => {
        setTest(test + 1);
    }, [test]);
    
    useEffect(() => {
        someLib && someLib.addCallback(onChange);
    
        return () => {
            someLib.removeCallback(onChange);
        }
    }, [someLib, onChange]);
    

    這樣做的好處是您不必在不同的地方追蹤 onChange 的依賴項。 onChange 的相依性列表現已關閉。

    回覆
    0
  • 取消回覆