是否可以在redux(react)中将initialState设置为null,然后将reducer内部更新为对象?

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

我有一个简单的商店:

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

或者我的方法完全错误?

reactjs redux react-redux redux-toolkit
1个回答
0
投票

可以对可能为空/未定义的对象引用使用保护。如果

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);
© www.soinside.com 2019 - 2024. All rights reserved.