从 redux 工具包导出额外的减速器

Exporting extra reducers from redux toolkit

前阵子做了一个todo list作为练习react和redux的方式。现在我正在尝试用 redux 工具包重写它,但在动作创建者方面遇到了一些麻烦。

这是旧的动作创作者:

export const changeDescription = (event) => ({
    type: 'DESCRIPTION_CHANGED',
    payload: event.target.value })

export const search = () => {
    return (dispatch, getState) => {
        const description = getState().todo.description
        const search = description ? `&description__regex=/${description}/` : ''
        axios.get(`${URL}?sort=-createdAt${search}`)
            .then(resp => dispatch({ type: 'TODO_SEARCHED', payload: resp.data }))
    } }

export const add = (description) => {
    return dispatch => {
        axios.post(URL, { description })
            .then(() => dispatch(clear()))
            .then(() => dispatch(search()))
    } }

export const markAsDone = (todo) => {
    return dispatch => {
        axios.put(`${URL}/${todo._id}`, { ...todo, done: true })
            .then(() => dispatch(search()))
    } }

export const markAsPending = (todo) => {
    return dispatch => {
        axios.put(`${URL}/${todo._id}`, { ...todo, done: false })
            .then(() => dispatch(search()))
    } }

export const remove = (todo) => {
    return dispatch => {
        axios.delete(`${URL}/${todo._id}`)
        .then(() => dispatch(search()))
    } }

export const clear = () => {
    return [{ type: 'TODO_CLEAR' }, search()] }

现在这是我正在处理的,我正在尝试复制旧版本的操作,但使用的是 redux 工具包:

export const fetchTodos = createAsyncThunk('fetchTodos', async (thunkAPI) => {
    const description = thunkAPI.getState().todo.description
    const search = description ? `&description__regex=/${description}/` : ''
    const response = await axios.get(`${URL}?sort=-createdAt${search}`)
    return response.data
})

export const addTodos = createAsyncThunk('fetchTodos', async (thunkAPI) => {
    const description =  thunkAPI.getState().todo.description
    const response = await axios.post(URL, {description})
    return response.data
})

export const todoReducer = createSlice({
    name: 'counter',
    initialState: {
        description: '',
        list: []
    },
    reducers: {
        descriptionChanged(state, action) {
            return {...state, dedescription: action.payload}
        },
        descriptionCleared(state, action) {
            return {...state, dedescription: ''}
        },

    },
    extraReducers: builder => {
        builder
         .addCase(fetchTodos.fulfilled, (state, action) => {
             const todo = action.payload
             return {...state, list: action.payload}
         })
         .addCase(addTodos.fulfilled, (state, action) => {
            let newList = state.list
            newList.push(action.payload)
            return {...state, list: newList}
        })
    }
})

问题是,我无法在任何地方找到如何导出我的额外减速器以便我可以使用它们。在 docs 中未找到任何内容。有人可以帮忙吗?

extraReducers

调用 createSlice 会根据您的参数创建一个具有属性 reducersactions 的切片对象。 reducersextraReducers 之间的区别在于只有 reducers 属性 生成匹配的动作创建者。但是两者都会为减速器添加必要的功能。

您已经在 extraReducers 属性 中正确地包含了您的 thunk reducer,因为您不需要为它们生成 action creator,因为您将使用您的 thunk action creator。

您可以直接导出 todoReducer.reducer(我个人称之为 todoSlice)。创建的 reducer 函数包括 reducers 和额外的 reducers。

编辑:Actions 与 Reducers

看来您对这里的一些术语感到困惑。 createSlice(您的 todoReducer 变量)创建的 slice 对象是一个包含 reducer 和 actions 的对象。

reducer 是一个单一的函数,它接受前一个状态和一个动作,returns 下一个状态。当您使用 reducer 时,应用程序中唯一的地方就是创建商店(通过调用 createStoreconfigureStore)。

redux 中的一个 action 是你 dispatch 的东西。您将在您的组件中使用这些。在您的代码中有四个动作创建器函数:两个是您使用 createAsyncThunk 创建的,两个是由 createSlice 创建的。这两个将在动作对象 todoReducer.actions.

单独导出

您可以 export 您的每个动作创建者单独导入它们,例如:

import {fetchTodos, descriptionChanged} from "./path/file";

您的 fetchTodosaddTodos 已经导出。另外两个你可以像这样解构和导出:

export const {descriptionChanged, descriptionCleared} = todoReducer.actions;

您可以在您的组件中这样调用它们:

dispatch(fetchTodos())

一起出口

您可以改为选择导出包含所有操作的单个对象。为了做到这一点,您可以将您的 thunk 与 slice 动作创建者结合起来。

export const todoActions = {
  ...todoReducer.actions,
  fetchTodos,
  addTodos
}

您将像这样导入:

import {todoActions} from "./path/file";

然后这样调用:

dispatch(todoActions.fetchTodos())