У меня есть редуктор-редуктор, сгенерированный с помощью createSlice
из комплекта-редуктора, называемый getOne
.
getOne
, извлекает из API и отправляет действия для состояния загрузки (startedLoading
,finishedLoading
, errorLoading
).
Я хотел бы также вызвать другой actionCreater, созданный в том же слайсе, с именем insert
с полученными данными. или напрямую обновите состояние из getOne
редуктора.
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: {
getOne: (state, action) => async (dispatch) => {
const { id, options } = action.payload
const url = `${apiEndpoint}/${modelName}/${id}`
const storeKey = `${modelName}_${id}`
dispatch(startedLoading({ key: storeKey }))
let response
try {
response = await fetch(url, fetchOptions)
} catch (error) {
dispatch(errorLoading({ key: storeKey }))
throw new Error(error)
}
const data = await response.json()
if (!response.ok) {
dispatch(errorLoading({ key: storeKey }))
throw new Error(`${response.status} loading ${url}`, { response, data, modelName, id, options })
} else {
// How would I update the store here?
// 1. reference the insert actionCreater somehow.
dispatch(insert({id: id, data: data))
// 2. construct the action manually
dispatch({action: `${modelName}/insert`, payload: {id: id, data: data))
// 3. Mutate the state here and rely immer. (I'm not sure exactly how that works)
state[modelName].byId[id] = data
dispatch(finishedLoading({ key: storeKey }))
}
},
insert: (state, action) => {
const { id, data } = action.payload
return {
...state,
byId: {
...state.byId,
[id ?? data.id]: data
}
}
},
// More reduceres
// { ... }
}
})
}