从react的官方文档中我们知道“React依赖于钩子被调用的顺序”,那么如果我想有条件地调用它,为钩子“保留”一个位置有什么错吗?
function Component({flag, depA, depB}) {
if (flag) {
// just "reserving a spot"
useEffect(() => {}, [null, null])
} else {
useEffect(() => {
// ... actual hook
}, [depA, depB])
}
return <></>
}
如果这个方法有效,那么它是否也适用于useCallback
、useLayoutEffect
、useMemo
、useImperativeHandle
?
我已经测试了所有这些,在更复杂的环境中,即使短绒抱怨,它似乎也能工作。
PS:如果它看起来像这样有点没用,那是因为最终目标是让钩子的主要部分懒洋洋地加载import()
,在导入被触发和解析之前,只需要为钩子保留位置。
3条答案
按热度按时间uelo1irk1#
我今天刚刚还在想这个问题,我认为虽然它“打破了规则”,但React无法区分两者之间的区别。
因此,虽然它违反了规则,但如果你有足够好的理由,了解风险,那么“规则”只是教条。
React基本上通过计算调用次数来知道哪个是useEffect钩子。有条件地调用
useEffect
是不好的,特别是因为useEffect
被调用的次数不能改变。您的示例是有条件的,但React无法检测到它,因为在这两种情况下都只调用了一次。
然而,你提到的例子似乎不需要这样做。有很好的理由用“正常”的方式做事,因为正如你从其他评论者那里看到的,它会引起混乱和惊讶,而我们不喜欢惊讶=)
如果您正在延迟加载某些功能,那么只要让
useEffect
钩子在它 * 准备好 * 时调用该函数即可。5us2dqdw2#
你不能有条件地调用useEffect,因为这违反了钩子的规则,你可以做以下操作:
xqkwcwgp3#
我的解决方案是这样的,它适用于所有的钩子,但是最好在必要的时候使用它,因为它可能会引起混乱和惊讶