redux 类型“WritableDraft〈{名称:字符串; }>'

jljoyd4f  于 2022-12-19  发布在  其他
关注(0)|答案(3)|浏览(268)

我是TypeScript新手。我正在尝试将TypeScript与Redux一起使用,但出现以下错误:Property 'user' does not exist on type 'WritableDraft<{ name: string; }>'.我在Youtube上一步一步地学习教程,但它对我的项目不起作用。
下面是我的代码:

import { createSlice } from '@reduxjs/toolkit';
import React from 'react';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    name: '',
  },
  reducers: {
    login: (state, action) => {
      state = action.payload;
    },
    logout: (state) => {
      state.user = null;
    },
  },
});

export const { login, logout } = userSlice.actions;

export const selectUser = (state: { user: { user: any } }) => state.user.user;

export default userSlice.reducer;
brccelvz

brccelvz1#

user状态切片的数据形状为{ name: string }

import { combineReducers, configureStore, createSlice } from '@reduxjs/toolkit';

export const userSlice = createSlice({
  name: 'user',
  initialState: {
    name: '',
  },
  reducers: {
    login: (state, action) => {
      state.name = action.payload;
    },
    logout: (state) => {
      state.name = '';
    },
  },
});

export const { login, logout } = userSlice.actions;

export const selectUser = (state: { user: { name: string } }) => state.user;

const store = configureStore({ reducer: combineReducers({ user: userSlice.reducer }) });
console.log(store.getState());
store.subscribe(() => {
  console.log('selectUser:', selectUser(store.getState()));
});

console.log(store.dispatch(login('John')));

日志:

{ user: { name: '' } }
selectUser: { name: 'John' }
{ type: 'user/login', payload: 'John' }
snvhrwxg

snvhrwxg2#

如果你反复检查你的代码,它的罚款。
将redux-toolkit的版本更改为以前的版本,在我的例子中,我使用了1.8.0,一切又开始工作了。
或者删除节点模块并运行npm installyarn

3xiyfsfu

3xiyfsfu3#

Redux将根据传递给createSlice函数的initialState值推断state的类型(在您的reducer中),如下所示:

...
initialState: {
  name: '',
}, // type of your state is: { name: string } - notice how it does not have a `user` property!
...

在你的reducer中,你会得到一个状态的WritableDraft示例作为第一个参数,如下所示:

logout: (state: WritableDraft<{ name: string }>) => {
  state.user = null; // 'user' property does not exist in your state type! (as defined in the `initialState`)
},

要完成我认为您正在尝试完成的任务,您所要做的就是将name变量抽象到user属性中,如下所示:

...
initialState: {
  user: { name: '' }
},
reducers: {
  login: (state, action) => {
    state.user = action.payload;
  },
  logout: (state) => {
    state.user = null;
  },
}
...

在这一点上,我建议显式地输入状态和操作负载。
例如:

export type User {
  name: string
}

export type UserState = {
  user: User | null
}

......在你的还原剂中:

login: (state, action: PayloadAction<User>) => {
  state.user = action.payload; // action.payload will be of type 'User'
},
logout: (state) => {
  state.user = null
}

无论如何,您似乎错过了教程中的一些内容,因为在您自己的代码中,您有一个选择器将状态定义为state: { user: { user: any } }。像上面这样显式定义状态类型,应该有助于在将来缓解这些问题。

相关问题