我有一个简单的商店:
import { userReducer } from './UserSlice';
export const store = configureStore({
reducer: {
user: userReducer,
},
});
我的目标是将用户对象的初始值设置为
null
,在我更新该用户后,它应该是一个User
对象:
export type User = {
id?: string;
username?: string;
role?: string;
};
所以我尝试创建一个初始状态为
null
的切片,但我有一个问题,打字稿抱怨说,如果我想从 null -> User
更新,该状态可能是 null
这是真的。
import { createSlice } from '@reduxjs/toolkit/react';
import { User } from '../types/User';
const userSlice = createSlice({
name: 'user',
initialState: null as User | null,
reducers: {
setUser: (state, action: { payload: User; type: string }) => {
state = action.payload;
},
setRole: (state, action: { payload: string; type: string }) => {
state.role = action.payload;
},
},
});
export const { setUser, setRole } = userSlice.actions;
export const userReducer = userSlice.reducer;
但即使尝试检查状态是否为空,我也不知道如何以沉浸式方式使用它。设置该对象的单个属性也存在问题。
所以我的问题是如何使用沉浸式风格来处理
null -> Object
?
或者我的方法完全错误?
可以对可能为空/未定义的对象引用使用保护。如果
state.role
存在,则仅访问 state
才能对其进行变异。
示例:
setRole: (state, action: { payload: string; type: string }) => {
if (state) {
state.role = action.payload;
}
},
您的
setUser
减速器也存在问题。在 Redux-Toolkit 中,您可以编写可变状态更新或,您可以返回新的状态引用,但不能两者兼而有之,并且您不应该重新分配state
。如果您想将 user
状态设置为有效负载,则只需 返回 有效负载作为下一个状态值。
import type { PayloadAction } from '@reduxjs/toolkit'
...
const userSlice = createSlice({
name: 'user',
initialState: null as User | null,
reducers: {
setUser: (state, action: PayloadAction<User>) => {
return action.payload; // <-- return new user object
},
setRole: (state, action: PayloadAction<string>) => {
if (state) { // <-- check that state exists
state.role = action.payload;
}
},
},
});
我发现维护始终存在的状态不变并使属性可选/可为空通常更容易。您仍然需要对这些属性进行空检查。
示例:
type UserState = {
user: User | null; // <-- nullable property
}
const initialState: UserState = {
user: null
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser: (state, action: PayloadAction<User>) => {
state.user = action.payload;
},
setRole: (state, action: PayloadAction<string>) => {
if (state.user) {
state.user.role = action.payload;
}
},
},
});
创建并导出选择器函数,这样您就无需在 UI 中编写
state.user.user
。
export const userSelector = (state: RootState) => state.user.user;
import { useSelector } from 'react-redux';
import { userSelector } from '../path/to/userSlice';
...
const user = useSelector(userSelector);