如何在React函数组件中条件性使用Hook?(Framer Motion场景示例)
如何在React函数组件中条件性使用Hook?(Framer Motion场景示例)
嘿,我懂你碰到的这个痛点——React的Hook规则卡得很死,绝对不能在条件语句、循环或者嵌套函数里调用Hook,你现在这么写在if里用useTransform肯定会触发React的报错对吧?别慌,咱们换个思路就能完美解决,还完全符合规则。
先给你明确核心思路:先在组件顶层无条件调用所有需要的Hook,再根据条件把Hook的结果赋值给目标对象。这样既遵守了Hook的调用顺序要求,又能实现你想要的条件性组装styles的效果。
修正后的代码示例
// 第一步:先在组件顶层调用所有可能用到的useTransform Hook const scaleUpTransform = useTransform(scrollYProgress, [0, 1], [1, 1.2]); const scaleDownTransform = useTransform(scrollYProgress, [0, 1], [1.2, 1]); const fadeInTransform = useTransform(scrollYProgress, [0, 1], [0, 1]); const fadeOutTransform = useTransform(scrollYProgress, [0, 1], [1, 0]); // 第二步:再根据条件把对应的变换结果赋值给styles对象 let styles = {}; if (scaleUp) { styles.scale = scaleUpTransform; } if (scaleDown) { styles.scale = scaleDownTransform; } if (fadeIn) { styles.opacity = fadeInTransform; } if (fadeOut) { styles.opacity = fadeOutTransform; }
为什么这么做可行?
React的Hook规则本质是依赖调用顺序的稳定性来跟踪每个Hook对应的状态/副作用。只要我们把所有Hook都放在组件顶层(没有任何条件包裹),不管你的scaleUp、fadeOut这些变量是什么值,Hook的调用顺序每次渲染都一致,React就能正确管理它们,不会出问题。
可选的简洁写法
如果想让代码更紧凑,也可以用条件属性的方式组装styles,逻辑和上面完全一致:
// 先统一调用Hook const scaleUpT = useTransform(scrollYProgress, [0, 1], [1, 1.2]); const scaleDownT = useTransform(scrollYProgress, [0, 1], [1.2, 1]); const fadeInT = useTransform(scrollYProgress, [0, 1], [0, 1]); const fadeOutT = useTransform(scrollYProgress, [0, 1], [1, 0]); // 用条件判断直接生成styles对象 const styles = { scale: scaleUp ? scaleUpT : scaleDown ? scaleDownT : undefined, opacity: fadeIn ? fadeInT : fadeOut ? fadeOutT : undefined };
注:这里如果scaleUp和scaleDown同时为true,会优先取后面的scaleDownT,和你原代码的覆盖逻辑保持一致。
避坑提醒
千万别想着用&&或者三元表达式直接在对象里调用Hook(比如...(scaleUp && { scale: useTransform(...) })),这种写法本质还是在条件里调用Hook,依然会违反规则,导致React报错。
备注:内容来源于stack exchange,提问作者jon
相关产品推荐
相关产品推荐

