【问题标题】:Exporting extra reducers from redux toolkit从 redux 工具包中导出额外的 reducer
【发布时间】:2021-06-02 11:29:38
【问题描述】:

我不久前做了一个待办事项列表,作为练习 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 中没有找到任何内容。有人可以帮忙吗?

【问题讨论】:

  • 只导出todoReducer.reducer。该切片包括reducersextraRedcuers
  • 你有一个错字dedescription,但你的操作似乎应该只更新列表中的一个待办事项,不是吗?

标签: reactjs redux redux-thunk redux-toolkit


【解决方案1】:

额外的减速器

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

您已在 extraReducers 属性中正确包含您的 thunk reducers,因为您不需要为这些生成动作创建者,因为您将使用您的 thunk 动作创建者。

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

编辑:Action 与 Reducers

您似乎对这里的一些术语感到困惑。 createSlice(你的todoReducer变量)创建的切片对象是一个同时包含reducer和actions的对象。

reducer 是一个单独的函数,它接受前一个状态和一个动作并返回下一个状态。当您使用 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 与切片动作创建者结合起来。

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

你会这样导入:

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

然后这样调用:

dispatch(todoActions.fetchTodos())

【讨论】:

  • 我正在尝试调用它们,但它给了我一个错误,说它不是一个函数。我这样称呼它:dispatch(todoReducer.fetchTodos())
  • 您对术语感到困惑。 fetchTodosaction 而不是 reducer。你需要import {fetchTodos} from './file'和打电话dispatch(fetchTodos());
猜你喜欢
  • 2021-11-07
  • 2022-10-02
  • 2021-03-03
  • 2021-09-15
  • 2021-06-30
  • 2021-01-27
  • 2021-06-24
  • 1970-01-01
  • 2018-09-18
相关资源
最近更新 更多