Ale*_*ide 5 javascript typescript reactjs redux redux-toolkit
我有这个切片:
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { IAuthState } from '../../types';
const initialState: IAuthState = {
isAuthenticated: false,
profile: null,
};
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
setAuthState(state, { payload }: PayloadAction<IAuthState>) {
console.log({ payload });
state = payload;
},
},
});
export const { setAuthState } = authSlice.actions;
export const authReducer = authSlice.reducer;
Run Code Online (Sandbox Code Playgroud)
这是标准的样板切片。
问题是,如果我这样做,我的状态不会更新。Redux devtools 说没有变化。我的有效负载是这样的:
{
isAuthenticated: true,
profile: {...} // big object
}
Run Code Online (Sandbox Code Playgroud)
但如果我这样分配:
reducers: {
setAuthState(state, { payload }: PayloadAction<IAuthState>) {
state.isAuthenticated = payload.isAuthenticated;
state.profile = payload.profile
},
},
Run Code Online (Sandbox Code Playgroud)
它更新状态。这是为什么?如何批量更新整个状态?
Emi*_*ron 16
无论它是使用 Redux Toolkit 的切片还是基本的 Redux reducer,如果您想替换整个状态,只需返回一个全新的值即可。
setAuthState(state, { payload }: PayloadAction<IAuthState>) {
return payload; // replaces the whole state
},
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)state = payload;
state是一个本地标识符,重新分配它在函数之外不会执行任何操作。尽管在 JavaScript 中,对象引用是按值传递的,所以state在函数内部改变对象也会改变在函数外部引用的任何地方的同一对象。
Redux Toolkit通过让开发人员改变传递的对象来简化状态更新state,这通常在不可变状态中被禁止,例如在 vanilla Redux 或 React 状态中。
它在内部使用Immer库,它允许您编写“改变”某些数据的代码,但实际上不可变地应用更新。这实际上使得减速器中的状态不可能意外改变。
在reducer中返回一个新对象只会替换整个状态并忽略代理对象。
state.profile=payload.profile,会发生这样的事吗?Yes, mutating each properties explicitly (taking advantage of RTK's usage of Immer) would do the same, with more code. Though if the payload ever has anymore properties, they wouldn't be included in the slice's state.
This could be what you want, no unwanted data ever gets to the state without explicitly adding it to the reducer. So it's not a bad thing to be explicit.
If you ever have lots of properties though, it could get annoyingly long to maintain.
setAuthState(state, { payload }) {
state.isAuthenticated = payload.isAuthenticated;
state.profile = payload.profile
state.thing = payload.thing
state.stuff = payload.stuff
state.foo = payload.foo
state.bar = payload.bar
// etc...
},
Run Code Online (Sandbox Code Playgroud)
What you could do if the payload gets longer, but you were in a situation where you don't want to replace the whole state, is to return a new object from spreading the current state and the payload.
setAuthState(state, { payload }) {
return {
...state,
...payload,
};
},
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5019 次 |
| 最近记录: |