在setState调用后使用react + immer时是否有更好的方法来操作下一个状态?

问题描述 投票:0回答:1

我使用 Typescript、React 和 Immer 来保存状态,其中包括一个配置文件列表,其中每个配置文件都有多个选项(存储为

profile.options: Option[]
)。我想在保存选项时,只需确保活动配置文件具有正确的选项数据,然后保存活动配置文件。

const { updateProfileList, getProfile } = useProfiles();
const [ activeProfileId, setActiveProfileId ] = useState<string>('dev');
const [ activeOptionId, setActiveOptionId ] = useState<string>("1");

const [ activeProfile, setActiveProfile ] = useImmer(getProfile(activeProfileId));
const [ activeOption, setActiveOption ] = useImmer(getOption(activeOptionId, activeProfileId));

const saveActiveProfile = (id: string = activeProfileId) => {
    updateProfileList((draft) => { 
        const target = draft[draft.findIndex((x)=>x.id === id)] = activeProfile;
        target.id = id; // ID of location should not change!!!
    });
}

const saveActiveOption = (id: string = activeOptionId) => {
    setActiveProfile((draft) => { 
        const target = draft.options[draft.options.findIndex((x)=>x.id === id)] = activeOption;
        target.id = id; // ID of location should not change!!!
    });
    // saveActiveProfile();
}

但是,由于 React 状态的工作方式,我怀疑这不会有预期的行为,因为

saveActiveProfile()
引用了
activeProfile
状态,直到当前渲染完成计算后才会更新。除了保存 Immer 的当前(草稿)并将其传递到保存函数之外,还有更好的方法吗?

编辑:以下是替代功能:

const saveProfile = (id: string, profile: Profile) => {
    updateProfileList((draft) => { 
        const target = draft[draft.findIndex((x)=>x.id === id)] = profile;
        target.id = id; // ID of location should not change!!!
    });
}

const saveActiveProfile = (id: string = activeProfileId) => {
    saveProfile(id, activeProfile);
}

const saveActiveOption = (id: string = activeOptionId) => {
    let intermediateActiveProfile = activeProfile;
    updateActiveProfile((draft) => { 
        const target = draft.options[draft.options.findIndex((x)=>x.id === id)] = activeOption;
        target.id = id; // ID of location should not change!!!
        intermediateActiveProfile = current(draft);
    });
    saveProfile(activeProfileId, intermediateActiveProfile);
}
reactjs typescript react-hooks immer
1个回答
0
投票

u2064您可以将更新后的状态直接传递给保存函数,而不是依赖 React 的异步状态更新。

const saveProfile = (id: string, profile: Profile) => {
    updateProfileList((draft) => { 
        const targetIndex = draft.findIndex((x) => x.id === id);
        draft[targetIndex] = { ...profile, id };
    });
}

const saveActiveProfile = (updatedProfile?: Profile) => {
    const profileToSave = updatedProfile || activeProfile;
    saveProfile(activeProfileId, profileToSave);
}

const saveActiveOption = (id: string = activeOptionId) => {
    let updatedProfile: Profile;
    setActiveProfile((draft) => { 
        const targetIndex = draft.options.findIndex((x) => x.id === id);
        draft.options[targetIndex] = { ...activeOption, id };
        updatedProfile = current(draft);
    });
    saveActiveProfile(updatedProfile);
}

另请查看 React 文档中的状态作为快照主题,它将帮助您更好地理解状态如何工作。

© www.soinside.com 2019 - 2024. All rights reserved.