Редукс-инструментарий использует actionCreater в том же слайсе от другого редуктора - PullRequest
0 голосов
/ 23 декабря 2019

У меня есть редуктор-редуктор, сгенерированный с помощью 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
      // { ... }
    }
  })
}
...