我不久前制作了一个待办事项列表,作为练习 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中没有找到任何内容。有人可以帮忙吗?
调用
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())
一起导出
export const todoActions = {
...todoReducer.actions,
fetchTodos,
addTodos
}
您可以像这样导入:
import {todoActions} from "./path/file";
然后这样打电话:
dispatch(todoActions.fetchTodos())
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;