我有一个与此类似的伪代码 React 组件:
const codeApplier = ({ code, prices }: Props) => {
const [isAccepted, setIsAccepted] = useState(false);
const applyCode = useCallback(async () => {
const validationResult = await callToApplyCode(code, prices);
if (validationResult.status === "OK") {
setIsAccepted(true);
} else {
setIsAccepted(false);
}
//do more stuff
}, [code, prices]);
useEffect(() => {
if (isAccepted) applyCode();
}, [prices]);
return <button onClick={applyCode} />;
};
重要部分:
现在,像这样的组件工作正常,但 linter 抱怨在 useEffect 上我没有列出所有依赖项。臭名昭著的详尽部门规则。
问题是:如果我将“applyCode”(甚至 isAccepted)添加到 useEffect 的依赖项中,如下所示:
useEffect(() => {
if (isAccepted) applyCode();
}, [isAccepted, applyCode, prices]);
然后 linter 很高兴,但是 useEffect 将在每次点击时重复调用。
这是可以禁用详尽依赖的情况之一吗? 或者有没有一种方法可以在不影响 linter 的情况下重构组件?
我看了这个评论:https://github.com/facebook/react/issues/14920#issuecomment-471070149 以及 StackOverflow 上的各种类似问题,但我无法找到针对我的具体案例的答案。
您可以使用 ref 来保存
isAccepted
的值,因此它可用于 useEffect
而无需将其设置为依赖项。
此外,您不需要使用
prices
作为 useEffect
的依赖项,因为每当 prices
更改时,applyCode
也会更改。然而,code
也会有这种效果,所以改变code
也会触发useEffect
。
const codeApplier = ({ code, prices }: Props) => {
const [isAccepted, setIsAccepted] = useState(false);
const isAcceptedRef = useRef(isAccepted); // save isAccepted as a ref as well
useEffect(() => { // update the ref on each render
isAcceptedRef.current = isAccepted;
});
const applyCode = useCallback(async () => {
const validationResult = await callToApplyCode(code, prices);
setIsAccepted(validationResult.status === "OK");
//do more stuff
}, [code, prices]);
useEffect(() => {
if (isAcceptedRef.current) applyCode(); // use the ref to decide when to apply
}, [applyCode]); // applyCode would change when prices or code change
return <button onClick={applyCode} />;
};