You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移旧项目到Redux Tool Kit时出现state.push不是函数错误怎么解决?

错误根因
  • 你的初始state是对象类型,只有数组才有push方法,你在reducer里对对象类型的state调用push直接触发类型错误。
  • Redux Toolkit 内置Immer支持可变写法修改state,你只需要直接给state的属性赋值即可,不需要调用数组方法。
  • 代码里还有3处附带错误需要同步修正:
    1. 触发action时不需要手动构造{type: xxx, payload: xxx}结构,直接调用action creator函数传参即可
    2. 请求头字段拼写错误:comtent-Type应为Content-Type
    3. registerSuccess里多解构了一层payload,会导致取值为空
修复后代码
import axios from 'axios';
import { createSlice } from '@reduxjs/toolkit';
import { setAlert } from '../alerts/alertSlice';

const slice = createSlice({
  name: 'auth',
  initialState: {
    token: localStorage.getItem('token'),
    isAuthenticated: null,
    loading: true,
    user: null,
  },
  reducers: {
    registerSuccess: (state, action) => {
      // 直接修改state属性即可,Immer会处理不可变性
      state.token = action.payload.token;
      state.user = action.payload.user;
      state.isAuthenticated = true;
      state.loading = false;
    },
    registerFail: (state) => {
      localStorage.removeItem('token');
      state.token = null;
      state.isAuthenticated = false;
      state.loading = false;
      state.user = null;
    },
  },
});

const { registerSuccess, registerFail } = slice.actions;

export default slice.reducer;

// Register User
export const register =
  ({ name, email, password }) =>
  async (dispatch) => {
    const config = {
      headers: {
        'Content-Type': 'application/json',
      },
    };

    const body = JSON.stringify({ name, email, password });

    try {
      const res = await axios.post('/api/users', body, config);
      // 直接调用action creator传payload
      dispatch(registerSuccess(res.data));
    } catch (err) {
      const errors = err.response.data.errors;

      if (errors) {
        errors.forEach((error) => dispatch(setAlert(error.msg, 'danger')));
      }

      dispatch(registerFail());
    }
  };
补充说明
  • 如果你更习惯原Redux的返回新对象写法,reducer也可以写成直接返回新对象的形式,两种写法都符合RTK规范:
    registerSuccess: (state, action) => {
      return {
        ...state,
        token: action.payload.token,
        user: action.payload.user,
        isAuthenticated: true,
        loading: false
      }
    }
    
  • RTK内置的Immer已经解决了state不可变性问题,不需要你手动通过展开运算符生成新对象,直接修改原state属性的写法更简洁。

内容的提问来源于stack exchange,提问作者Ricksta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:36:01