英文:
Use a state property inside the prepare callback (Redux Toolkit)
问题
I have a store with this initialState
:
const initialState = {
todos : [] // [{ task: "todo something", description: "have todo something" }, ...]
maxTodos: 5
....
}
I want inside the prepare
callback to id
new todo that I will add, based on the length of the current todos
array.
reducers: {
addTodo: {
reducer: (state, action) => {
return { ...state, todos: [...state.todos, action.payload]}
},
prepare: (state, text) => {
const id = state.todos?.length; // the error is some what here
return { payload: { id, text } }
},
},
....
Is there a way to access state
inside the prepare
callback to the slice state?
Or a different approach that can solve this?
The easy solution to send from the dispatch
the length of the todo's or the create a nanoId()
inside the prepare
.
For now I don't want to implement this approach (written above), I want to send via the dispatch
only the new todo that I want to add, and the id will be transparent to the dispatch
because I want to control the todo's via their position in the array.
英文:
I have a store with this initialState
:
const initialState = {
todos : [] // [{ task: "todo something", description: "have todo something" }, ...]
maxTodos: 5
....
}
I want inside the prepare
callback to id
new todo that I will add, based on the length of the current todos
array.
reducers: {
addTodo: {
reducer: (state, action) => {
return { ...state, todos: [...state.todos, action.payload]}
},
prepare: (state, text) => {
const id = state.todos?.length; // the error is some what here
return { payload: { id, text } }
},
},
....
Is there a way to access state
inside the prepare
callback to the slice state?
Or a different approach that can solve this?
The easy solution to send from the dispatch
the length of the todo's or the create a nanoId()
inside the prepare
.
For now I don't want to implement this approach (written above), I want to send via the dispatch
only the new todo that I want to add, and the id will be transparent to the dispatch
because I want to control the todo's via their position in the array.
答案1
得分: 3
prepare
函数用于在reducer函数接收操作对象之前对其进行预处理。这是编写操作创建者的一种方式,可以接受不止一个参数,或者向操作对象添加元数据。
在这里,我看不出添加一个id
属性的用例,该属性的值是状态中数组的长度,这是因为prepare
函数无法访问状态对象。我的建议是在reducer函数中计算id
,因为在那里状态是可访问的。
示例:
reducers: {
addTodo: (state, action) => {
state.todos.push({
text: action.payload,
id: state.todos.length,
})
},
...
这可能有点愚蠢,但如果您真的只是想要一个操作创建者,返回一个带有text
和基于当前状态生成的id
属性的payload
,您可以使用createAsyncThunk
并从ThunkAPI
中访问getState
。
示例:
const addTodo = createAsyncThunk(
"todos/addTodo",
(text, { getState }) => ({
text,
id: getState().todos.length, // *
})
);
const todosSlice = createSlice({
name: "todos",
initialState,
reducers: {
...
},
extraReducers: builder => {
builder.addCase(addTodo.fulfilled, (state, action) => {
state.todos.push(action.payload);
});
},
});
**注意:**根据reducers如何组合以形成传递给存储配置器的根reducer,可能需要编辑以选择正确的状态。
英文:
The prepare
function is used to preprocess the action object prior to the reducer function receiving it. It's a way to write action creators that take more than a single argument, or to add meta data to the action object.
I don't see much of a use case here for adding an id
property that is the length of the array in state from the prepare
function. The prepare
function just doesn't have access to the state object. My suggestion would be to just compute the id
in the reducer function where the state is accessible.
Example:
reducers: {
addTodo: (state, action) => {
state.todos.push({
text: action.payload,
id: state.todos.length,
})
},
...
This would possibly be a bit silly, but if you really just wanted an action creator that returned a payload
with the text
and a generated id
property based on the current state you could use createAsyncThunk
and access getState
from the ThunkAPI
.
Example:
const addTodo = createAsyncThunk(
"todos/addTodo",
(text, { getState }) => ({
text,
id: getState().todos.length, // *
})
);
const todosSlice = createSlice({
name: "todos",
initialState,
reducers: {
...
},
extraReducers: builder => {
builder.addCase(addTodo.fulfilled, (state, action) => {
state.todos.push(action.payload);
});
},
});
*Note: Edit to select correct state based on how the reducers are combined to form the root reducer passed to the store configurator.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论