我正在编写一个自定义挂钩,我需要从useEffect发送更新值,但isValid值丢失,发送总是false。如果我在useEffect中遗漏了什么,或者我以不正确的方式使用
export const useBasicValidity = (numb, name, dd, month, year) => {
let isValid = false;
const checkIsValid = (numb, name, dd, month, year) => {
// some validation checks
return boolean value;
};
useEffect(() => {
isValid = checkIsValid(numb, name, dd, month, year);
}, [numb, name, dd, month, year]);
return isValid;
};
这是我运行过的一个非常常见的模式。如果你想做点什么,在这种情况下,当一些变量发生变化时,检查验证,并将结果存储为变量。
请记住,使用效果发生在每个文档的渲染之后。
请改用useEffect。传递给useEffect的函数将运行在将渲染提交到屏幕之后。将效果视为逃离React纯粹的功能世界进入命令世界
因此,到useEffect
运行时,isValid
已经完成了您想做的一切。您需要运行useEffect
,因为您的一个变量发生了更改,并使用isValid
的新值触发新的渲染。因此,isValid
应该处于状态。将您的代码更改为:
const [isValid, setIsValid] = useState(false);
const checkIsValid = (numb, name, dd, month, year) => {
// some validation checks
return boolean;
};
useEffect(() => {
setIsValid(checkIsValid(numb, name, dd, month, year));
}, [numb, name, dd, month, year]);
但是,还有另一种方法可以做到这一点!有时可以将状态和效果组合到useMemo
:中
const checkIsValid = (numb, name, dd, month, year) => {
// some validation checks
return boolean;
};
const isValid = useMemo(() => {
setIsValid(checkIsValid(numb, name, dd, month, year));
}, [numb, name, dd, month, year]);
根据文档,如果checkIsValid
没有在其他地方使用,或者被列为该效果/备忘录的依赖项,那么它应该在您的备忘录/效果中。第二个选项作为依赖项,将导致它运行每次渲染,因为每次渲染都会重新创建函数(即使它做同样的事情(。因此,当React检查useEffect
的依赖关系时,它会看到对checkIsValid
的新函数的引用,并触发效果。太糟糕了。因此,您需要使用useCallback
:的函数
const checkIsValid = useCallback((numb, name, dd, month, year) => {
// some validation checks
return boolean;
}, [dependencies here]);
const isValid = useMemo(() => {
setIsValid(checkIsValid(numb, name, dd, month, year));
}, [numb, name, dd, month, year, checkIsValid]);
如果您使用useEffect
,同样的想法也适用。现在,只有当函数真的发生了变化时,这个函数才会成为一个新的引用(无论如何,这就是你想要的(。