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

问题描述 投票:0回答:2

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

reactjs redux redux-thunk redux-toolkit
2个回答
11
投票

额外减速器

调用

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

您已正确地将 thunk 缩减器包含在

extraReducers
属性中,因为您不需要为这些生成动作创建器,因为您将使用 thunk 动作创建器。

你可以直接导出

todoReducer.reducer
(我个人称之为
todoSlice
)。创建的减速器函数包括减速器和额外的减速器。

编辑:动作与减速器

您似乎对这里的一些术语感到困惑。由

createSlice
(您的
todoReducer
变量)创建的切片对象是一个包含减速器和动作的对象。

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

configureStore
)。
redux 中的

action

是您dispatch 的事情。您将在您的组件中使用它们。在您的代码中有四个动作创建器函数:两个是您使用

createAsyncThunk
创建的,另外两个是由
createSlice
创建的。这两个将位于操作对象中
todoReducer.actions
单独导出

您可以单独

export

每个动作创建者并导入它们,如下所示:

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

您的 
fetchTodos

addTodos
已导出。另外两个你可以像这样解构和导出:
export const {descriptionChanged, descriptionCleared} = todoReducer.actions;

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

dispatch(fetchTodos())

一起导出

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

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

您可以像这样导入:

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

然后这样打电话:

dispatch(todoActions.fetchTodos())



0
投票

const rootReducer = combineSlices({ counter: counterSlice.reducer, currentLA: currentLocalArea.reducer }); export const store = configureStore({ reducer: rootReducer }) export const rootActions = { ...counterSlice.actions, ...currentLocalArea.actions } export default rootReducer;

© www.soinside.com 2019 - 2024. All rights reserved.