React Recoil异步调用删除API报错:不支持异步Selector Set
Recoil异步删除数据报错"Async selector sets are not currently supported"的解决方法
问题场景
用React Recoil替代Redux实现Season记录删除功能,调用seasonApi.deleteSeason接口后数据库已成功删除对应记录,但触发错误提示:"Recoil: Async selector sets are not currently supported."
相关代码片段:
Selector Family 定义
export const deleteSeason = selectorFamily({ key: "deleteSeason", set: () => async ({ get, set }, seasonId) => { return await seasonApi.deleteSeason(seasonId); }, });
组件内引用与调用
const setSeasonDelete = useSetRecoilState(deleteSeason()); const onDeleteSeason = async (selectedSeason) => { setInEditMode(false); try { await setSeasonDelete(selectedSeason.Id); } catch (error) { deleteSeasonFailNotification("error"); } };
核心原因
Recoil的Selector 不支持异步的set方法,set回调必须是同步执行的逻辑,这是框架的设计限制。
正确实现方式
方式一:组件内直接处理异步逻辑
将API调用移到组件的删除函数中,接口调用成功后同步更新Recoil的状态(比如存储Season列表的Atom):
// 假设存在存储Season列表的Atom export const seasonsState = atom({ key: 'seasonsState', default: [], }); // 组件内删除逻辑 const [seasons, setSeasons] = useRecoilState(seasonsState); const onDeleteSeason = async (selectedSeason) => { setInEditMode(false); try { // 先执行异步删除API await seasonApi.deleteSeason(selectedSeason.Id); // 成功后同步更新Recoil状态,移除目标记录 setSeasons(prevList => prevList.filter(season => season.Id !== selectedSeason.Id)); } catch (error) { deleteSeasonFailNotification("error"); } };
方式二:用useRecoilCallback封装复用逻辑
如果删除逻辑需要在多个组件复用,可通过useRecoilCallback封装异步操作与状态更新:
// 组件内封装删除逻辑 const deleteSeason = useRecoilCallback(({ set }) => async (seasonId) => { try { await seasonApi.deleteSeason(seasonId); // 更新列表状态 set(seasonsState, prevList => prevList.filter(season => season.Id !== seasonId)); } catch (error) { deleteSeasonFailNotification("error"); } }, []); // 调用删除逻辑 const onDeleteSeason = (selectedSeason) => { setInEditMode(false); deleteSeason(selectedSeason.Id); };
内容的提问来源于stack exchange,提问作者CJH
相关产品推荐
相关产品推荐

