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

LGi*_*nez 1 reactjs redux redux-thunk redux-toolkit

我不久前制作了一个待办事项列表,作为练习 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()] }
Run Code Online (Sandbox Code Playgroud)

现在这是我正在研究的一个,我正在尝试复制旧的操作,但使用 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}
        })
    }
})
Run Code Online (Sandbox Code Playgroud)

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

Lin*_*ste 11

额外减速器

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

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

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

编辑:Actions 与Reducers

您似乎对这里的一些术语感到困惑。createSlice(您的变量)创建的切片对象todoReducer是一个包含减速器和操作的对象。

减速器是一个单一函数,它接受前一个状态和一个操作并返回下一个状态。当您使用减速器时,应用程序中的唯一位置是创建存储(通过调用createStoreconfigureStore)。

redux 中的一个动作是你所做的事情dispatch。您将在您的组件中使用它们。在您的代码中有四个动作创建器函数:两个是您使用创建的createAsyncThunk,两个是由createSlice. 这两个将在 actions 对象中todoReducer.actions

单独导出

您可以export单独导入每个动作创建者,如下所示:

import {fetchTodos, descriptionChanged} from "./path/file";
Run Code Online (Sandbox Code Playgroud)

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

export const {descriptionChanged, descriptionCleared} = todoReducer.actions;
Run Code Online (Sandbox Code Playgroud)

您可以在组件中调用它们,例如:

dispatch(fetchTodos())
Run Code Online (Sandbox Code Playgroud)

一起出口

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

export const todoActions = {
  ...todoReducer.actions,
  fetchTodos,
  addTodos
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样导入:

import {todoActions} from "./path/file";
Run Code Online (Sandbox Code Playgroud)

并像这样调用:

dispatch(todoActions.fetchTodos())
Run Code Online (Sandbox Code Playgroud)