从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先生(
已完成(获取乐器、获取音乐家数据),
(状态、动作)=>{
//或者你需要的其他逻辑
返回动作。有效载荷。仪器;
}
)
}
这最终应该可以做到