从Redux/Redux工具箱中的另一个切片调度还原程序 设置
在我的后端,我有一个从Redux/Redux工具箱中的另一个切片调度还原程序 设置,redux,redux-toolkit,Redux,Redux Toolkit,在我的后端,我有一个音乐家模型,它可以有许多乐器s或歌曲s。RESTAPI有单独的路径来获取所有音乐家,获取音乐家的所有乐器,获取音乐家的所有歌曲,等等 我的根状态如下所示: musicians: [], instruments: [], songs: [] 然后,我有3个Redux工具包“切片”,用于管理状态的各个部分。例如,instrumentsSlice有一个名为fetchInstruments的异步thunk,它调用rest API为特定音乐家提取乐器,然后在ExtraReducer中
音乐家
模型,它可以有许多乐器
s或歌曲
s。RESTAPI有单独的路径来获取所有音乐家,获取音乐家的所有乐器,获取音乐家的所有歌曲,等等
我的根状态如下所示:
musicians: [],
instruments: [],
songs: []
然后,我有3个Redux工具包“切片”,用于管理状态的各个部分。例如,instrumentsSlice
有一个名为fetchInstruments
的异步thunk,它调用rest API为特定音乐家提取乐器,然后在ExtraReducer中实现:
extraReducers: {
[fetchInstruments.fulfilled]: (state, action) => {
return action.payload.map(instrument => {
instrument.id = nextInstrumentId++;
return instrument;
});
},
....
}
在特定音乐家的页面上:fetchInstruments
和fetchSongs
被调度,它们调用各自的API来更新状态。然后,我使用的选择器只过滤与该页面的特定音乐家ID匹配的乐器或歌曲
问题
到目前为止,我已经能够使用这3个单独的切片。现在,我想创建一个仪表板,在这里我可以查看所有音乐家的摘要信息。我意识到为每个列出的音乐家调用3个XHR请求是没有意义的,因此我创建了一个新的rest路由,返回所有音乐家嵌套的信息,fetchAllMusicianData
,即:
musicians: [
{
name:,
instruments: [],
songs: []
},
...
]
问题
不知何故,我需要将这个嵌套的音乐家/乐器/歌曲数据放到我的状态树中。但是,理想情况下,我不希望复制fetchInstruments
或fetchSongs
还原程序中存在的逻辑(例如在上面的extrareducer
代码中创建本地ID)
当fetchAllMusicianData
调用完成时,我是否可以调用其他片段来运行它们的方法,如fetchInstruments.implemented
?有什么方法可以更新这些信息吗?或者,我应该以不同的方式组织我的国家吗
提前谢谢你的帮助 让我们先解决一件事。一般情况下,您不应像这样增加ID:
extraReducers: {
[fetchInstruments.fulfilled]: (state, action) => {
return action.payload.map(instrument => {
instrument.id = nextInstrumentId++;
return instrument;
});
},
....
}
由于nextInstrumentId
是一个外部变量,您在这里引入了一个副作用-因此,如果您要使用devtools重播您的操作(例如,“跳过”一个操作将从一开始就重播),您将再次获得不同的ID。如果您有引用这些ID(或本地状态或url参数等)的其他操作,则该引用将中断
因此,这些ID要么只需要基于reducer中可用的信息生成,要么更好,直接在createAsynchThunk
调用中生成。
这样做的副作用是完全好的
现在,回到手头的问题:
我的建议是更改fetchInstruments
的返回值,使其与fetchAllMusicianData
asyncThunk共享相同的(部分)结构
所以
const fetchInstruments=createasynchunk('fetchInstruments',()=>{
//获取数据:
const fetched=fetchData();
//应用一些ID
const instruments=fetched.map(instrument=>({…instrument,id:nextInstrumentId++}))
//将其作为对象的一部分返回
返回{instruments}
}
然后对您的获取所有MusicianData
执行相同的操作:
const fetchAllMusicianData=createasynchunk('fetchAllMusicianData',()=>{
//获取数据应用一些ID,你就知道要点了
//将其作为对象返回
返回{乐器、歌曲、名称}
}
现在,您可以让所有的切片只处理fetchInstruments
和fetchallmusicialdata
(或fetchSongs
和fetchallmusicialdata
等)相同的操作
使用带符号的extraReducers builder表示法:
外部减速器(生成器){
建设者
addMatcher先生(
已完成(获取乐器、获取音乐家数据),
(状态、动作)=>{
//或者你需要的其他逻辑
返回动作。有效载荷。仪器;
}
)
}
这最终应该可以做到