我使用 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);
}
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 文档中的状态作为快照主题,它将帮助您更好地理解状态如何工作。