16

我有我的减速机


const userAuthSlice = createSlice({
    name: "userAuth",
    initialState: {
        token: '',
    },
    reducers: {
        setToken: (state, action) => state.token = action.payload.test,
    },
});

我有我的调度命令

<button
   value={text.sign_in.submit}
   onClick={() => dispatch(userAuthSlice.actions.setToken({test:"test"}))}

/>

当我按下按钮时,我得到的是这个错误:

在此处输入图像描述

我已经隔离了所有内容,以确保这是问题所在,仅此而已。

为什么会弹出这个错误?

4

7 回答 7

34

问题是使用没有花括号的箭头函数作为减速器,因为它充当隐式返回语句。因此,您既要 mutating state.token又要返回分配的结果。

根据有关返回数据的 Immer 文档,有几种方法可以解决此问题:

  • void在赋值前面添加运算符
  • 将赋值用花括号括起来,使其成为函数体

所以setToken减速器可以更新void

setToken: (state, action) => void(state.token = action.payload.test)
于 2020-03-23T15:16:19.797 回答
4

正确答案

使用代替

const userAuthSlice = createSlice({
    name: "userAuth",
    initialState: {
        token: '',
    },
    reducers: {
        setToken: (state, action) => state.token = action.payload.test,
    },
});

使用这个{我刚刚添加了括号}

const userAuthSlice = createSlice({
    name: "userAuth",
    initialState: {
        token: '',
    },
    reducers: {
        setToken: (state, action) => { state.token = action.payload.test}, // <<= Change Here
    },
});
于 2021-10-15T07:07:04.710 回答
2

学习要点IMMER

  1. 如果您从配方函数返回草稿以外的任何内容,则该返回值将替换状态
  2. 你主要想改变草稿来改变状态,**所以修改后返回草稿是可选的**,immer无论如何都会返回最终草稿
  3. 如果您从函数返回任何其他内容,recipe则根据第 1 点,新的返回值将替换状态
  4. 第 3 点没问题,前提是您不修改配方功能中的草稿。即您可以选择两者之一
    。修改草稿->返回草稿或未定义,都可以
    b. 想要返回一些新的值,那么根本不要碰草稿

现在来回答这个问题。这是你的减速器功能

(state, action) => state.token = action.payload.test

这个函数做了两件事,
1. 修改状态
2. 返回 action.payload.test

所以它违反了第 4 点,因此来自 Immer 库的错误

在这种特定情况下,意图只是修改状态,所以我们必须撤消现有的返回void

setToken: (state, action) => void(state.token = action.payload.test)

但是,Immer 库建议使用代码块来确保跨大型代码库的一致性,此代码块隐式返回 undefined

setToken: (state, action) => { state.token = action.payload.test } 
于 2020-07-13T05:41:30.713 回答
0

代替

 state.token = action.payload.token

采用

 const token = action.payload.token
 state.token = token

常量是不可变的,将 action.payload 内容分配给常量为我解决了一个问题(请注意,如果有效负载是一个对象,则不需要

createSlice 的工作示例:

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

export const slice = createSlice({
  name: 'login',
  initialState: {
      username: "Foo",
      password: "AAA",
      authorized : false
  },
  reducers: {
    setUsername: (state, action) => {

      const value = action.payload
      state.username = value // action.payload.username

    },
    setPassword: (state, action) => {

      const value = action.payload
      state.password = value // action.payload.password

    },
    logon: (state, action) => {

      state.username = action.payload.username
      state.password = action.payload.password
      state.authorized = true

    },
    logoff: state => state.authorized = false
  },
});
于 2020-04-05T19:58:34.440 回答
0

对于那些使用 PullState 的人,我的问题在于语法:

我有:

 const onUpdate = (value: any) => {
    someStore.update((s) => (s.value = value));
 };

但必须是:

 const onUpdate = (value: any) => {
    someStore.update((s) => {
       s.value = value;
    });
 };

出于某种原因,不喜欢第一种方法中声明的箭头函数。

于 2022-03-04T14:18:12.980 回答
-1

尝试检查此链接以进行无参考复制

于 2021-06-03T23:11:34.127 回答
-3

你可能会忘记休息;在你的 reducer.js 文件中声明;

 case LOGIN_USER_ERROR_RESET:
        draft.errormsg = '';
        draft.loading = false;
        draft.error = false;
        break;
于 2020-06-15T13:50:53.037 回答