redux - redux-toolkit 在来自另一个 thunk reducer 的同一切片中使用 actionCreater
问题描述
我有一个createSlice
从 redux-toolkit 生成的 redux-thunk reducer,名为getOne
.
getOne
从 API 获取并调度加载状态的操作,( startedLoading
, finishedLoading
, errorLoading
)。
我还想调用在insert
使用结果数据调用的同一切片中创建的另一个 actionCreater。或者直接从getOne
reducer更新状态。
import { createSlice } from "@reduxjs/toolkit"
import { startedLoading, finishedLoading, errorLoading } from '../slices/loadingSlice'
const apiEndpoint = "/api/v1"
const fetchOptions = { headers: { "Content-Type": "application/json" } }
const createModelSlice = function (modelName) {
return createSlice({
name: modelName,
initialState: {byId: {}},
reducers: {
insert: (state, action) => {
// ...
},
getOne: (state, action) => async (dispatch) => {
// ...
try {
const response = await fetch(/* */)
// How would I update the store here?
// 1. reference the insert actionCreater somehow.
dispatch(insert({id: id, data: response))
// 2. construct the action manually
dispatch({action: `${modelName}/insert`, payload: {id: id, data: response))
// 3. Mutate the state here and rely immer. (I'm not sure exactly how that works)
state[modelName].byId[id] = response
dispatch(finishedLoading({ key: /* */ }))
} catch (error) {
dispatch(errorLoading({ key: /* */ }))
}
},
// ...
}
})
}
解决方案
我错过了有关切片无法使用 thunk 的部分文档。无论哪种方式,它都不起作用,因为 thunk 动作不会映射到减速器,而是将其他动作分派到多个其他减速器/动作。
创建切片后,我向切片操作添加了 thunk 操作。这样我可以参考其他动作
import { createSlice } from "@reduxjs/toolkit"
const slice = createSlice({
name: name,
initialState: { byId: {} },
reducers: { /* */ }
}
slice.actions.myThunkAction = payload => async (dispatch, state) => {
// ...
slice.actions.nonThunkAction({ id: id, data: data})
slice.actions.anotherNonThunkAction({ index payload.index, data: data.map( /* */ )})
}
import { createSlice } from "@reduxjs/toolkit"
import { startedLoading, finishedLoading, errorLoading } from '../slices/loadingSlice'
import encodeURLParams from '../tools/encodeURLParams'
const apiEndpoint = "/api/v1"
const fetchOptions = { headers: { "Content-Type": "application/json" } }
const createModelSlice = function (modelName) {
const slice = createSlice({
name: modelName,
initialState: { byId: {} },
reducers: {
insert: (state, action) => {
// ...
},
bulkInsert: (state, action) => {
// ...
},
}
})
slice.actions.loadMany = payload => async (dispatch, state) => {
dispatch(startedLoading({ key: /* */ }))
try {
const response = await fetch(/* */)
dispatch(slice.actions.insert(response))
dispatch(finishedLoading({ key: /* */ }))
} catch (error) {
dispatch(errorLoading({ key: /* */ }))
}
}
slice.actions.loadOne = payload => async (dispatch, state) => {
dispatch(startedLoading({ key: /* */ }))
try {
const response = await fetch(/* */)
dispatch(slice.actions.bulkInsert(response))
dispatch(finishedLoading({ key: /* */ }))
} catch (error) {
dispatch(errorLoading({ key: /* */ }))
}
}
return slice
}
export default createModelSlice
推荐阅读
- powerbi - 检查列值在 power bi 中重复的次数
- ios - 如何动态设置自定义 UIView 类的高度,并将 XIB 添加到垂直堆栈视图?
- r - 多个变量的夏皮罗测试错误:
- javascript - 如何从子组件 onClick 访问和 setState() 的父组件
- python - 无法比较日期变量和熊猫数据框之间的日期
- c++ - 如何使用 C++ 显示连接到网络的设备的名称和 IP 地址
- angular - ngIf 可以在 Angular 1.5 中引用嵌套 ngFor 中的变量。如何在 Angular 10 中实现同样的效果?
- node.js - 在 GCP 环境之外进行 POST 调用以创建工作负载身份
- scala - 如何使用 spark scala 将整数转换为 Varchar(8)
- javascript - ReactJS如何在刷新页面时保持状态值