我想从useNumber
自定义钩子返回一个helper函数,它将检查该数字是否大于传递给此函数的其他数字。
我还想重新计算这个函数的布尔结果只有当数字已经改变。
下面的代码似乎可以实现(isLargerThan
只在number.value
改变时运行,而不是在每次重新渲染时运行;您可以通过检查控制台日志来判断):
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 = (i: number) =>
React.useMemo(() => {
console.log("running isLargerThan");
return value > i;
}, [value]);
return { value, isLargerThan, reset: setValue };
};
const App = () => {
const number = useNumber();
const [renderTrigger, setRenderTrigger] = React.useState<number>();
return (
<div>
<div>Will change on each render: {getNumber()}</div>
<div>Will change on page reload: {number.value}</div>
<div>Larger than 50?: {String(number.isLargerThan(50))}</div>
<button onClick={() => setRenderTrigger(getNumber())}>
Trigger render {renderTrigger}
</button>
<button onClick={() => number.reset(getNumber())}>Reset number</button>
</div>
);
};
const rootElement = document.getElementById("root");
render(<App />, rootElement);
然而,我正在打破“钩子规则”来实现这一目标:useMemo
未在顶层使用,因此出现错误:
我怎样才能做得更好?
现场示例:https://codesandbox.io/s/react-ts-playground-forked-2urxn2?file=/src/index.tsx
1条答案
按热度按时间vbkedwbf1#
有一个非常简单的解决方案可以达到预期的效果:
您应该尝试
useCallback
,因为它 * 仅 * 在value
更新时更新您传递给它的函数。