[英]State variable inside a function defined within useEffect hook is not updating when value changes
[英]Run helper function in a hook only when some hook state changes
我如何調整下面的代碼,以便日志消息console.log("This should log only on resetting the number")
僅在單擊“Reset number”按鈕時記錄,而不是在單擊“Rerender”按鈕時記錄?
import * as React from "react";
import { render } from "react-dom";
const getNumber = () => Math.round(Math.random() * 100);
const useNumber = () => {
const [value, setValue] = React.useState<number>(getNumber());
const isLargerThan = React.useMemo(() => {
const func = (i: number) => {
console.log("This should log only on resetting the number");
return value > i;
};
return func;
}, [value]);
const reset = () => setValue(getNumber());
return { value, isLargerThan, reset };
};
const App = () => {
const number = useNumber();
const [trigger, setTrigger] = React.useState(false);
console.log("rerendering");
return (
<div>
<div>
Is {number.value} larger than 50?: {String(number.isLargerThan(50))}
</div>
<button onClick={number.reset}>Reset number</button>
<button onClick={() => setTrigger(!trigger)}>Rerender</button>
</div>
);
};
const rootElement = document.getElementById("root");
render(<App />, rootElement);
實例: https ://codesandbox.io/s/react-ts-playground-forked-2urxn2?file=/src/index.tsx:305-390
據我了解,您是在渲染方法中直接調用useCallback
函數,因此每次運行重新渲染時,都會再次調用該函數。 避免這種情況的一種方法是不讓您的 useMemo 返回一個函數,而是一個簡單的比較。 您還可以使用一個值來初始化您的掛鈎,以存儲您正在比較的數字,並在useMemo
依賴項中使用它。 我做了一些看起來像這樣的東西,它似乎按照你的意圖工作。
const getNumber = () => Math.round(Math.random() * 100);
const useNumber = (val) => {
const [value, setValue] = React.useState<number>(getNumber());
const isLargerThan = React.useMemo(() => {
console.log("This should log only on resetting the number");
return value > val;
}, [value, val]);
const reset = () => setValue(getNumber());
return { value, isLargerThan, reset };
};
const App = () => {
const [val, setVal] = React.useState(50)
const number = useNumber(val);
const [trigger, setTrigger] = React.useState(false);
console.log(number.isLargerThan)
return (
<div>
<div>
Is {number.value} larger than {val}?: {String(number.isLargerThan)}
</div>
<button onClick={number.reset}>Reset number</button>
<button onClick={() => {setTrigger(!trigger)}}>Rerender</button>
</div>
);
};
const rootElement = document.getElementById("root");
render(<App />, rootElement);
有一個非常簡單的解決方案可以達到預期的結果:
const isLargerThan = () =>
React.useCallback((i: number) => {
console.log("updating the stored function");
return value > i;
}, [value]);
您應該嘗試useCallback
因為它只會在value
更新時更新您傳遞給它的函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.