如何在Recoil中为atomFamily动态赋值且不违反React Hook规则?
核心解决方案:使用useRecoilCallback实现动态更新
首先修正示例中的笔误:Recoil提供的是atomFamily工厂函数,不属于Hook,不需要加use前缀,可在任意位置调用。
你之前的写法违反Hook规则的原因是:useSetRecoilState属于Hook,必须在组件/自定义Hook的顶层同步调用,不能在异步回调、循环、条件分支中动态调用,而接口返回的index是异步获取的,无法在顶层提前确定参数。
正确实现代码如下:
修正后的atomFamily定义
import { atomFamily, useRecoilCallback } from 'recoil' type Foo = unknown & { index: string } const myAtomFamily = atomFamily<Foo | null, string>({ key: 'foo', default: null, }) declare const fetchFromApi = () => Promise<Foo[]>
自定义Hook实现
const myHook = () => { // 顶层调用useRecoilCallback,符合Hook调用规则 const saveFoosToAtomFamily = useRecoilCallback(({ set }) => async () => { const foos = await fetchFromApi() foos.forEach(foo => { // 动态传入index获取对应atom,调用set方法更新 set(myAtomFamily(foo.index), foo) }) }, []) useEffect(() => { saveFoosToAtomFamily() }, [saveFoosToAtomFamily]) }
实现逻辑说明
useRecoilCallback是Recoil提供的原生Hook,允许你在回调内部访问Recoil的状态更新能力,不需要提前为每个可能的key调用useSetRecoilState- 回调内部可以使用异步获取到的动态
index参数生成对应的atom实例,再调用set方法完成更新,全程不会触发Hook规则校验报错
内容的提问来源于stack exchange,提问作者user1713450
相关产品推荐
相关产品推荐

