迁移旧项目到Redux Tool Kit时出现state.push不是函数错误怎么解决?
错误根因
- 你的初始state是对象类型,只有数组才有
push方法,你在reducer里对对象类型的state调用push直接触发类型错误。 - Redux Toolkit 内置Immer支持可变写法修改state,你只需要直接给state的属性赋值即可,不需要调用数组方法。
- 代码里还有3处附带错误需要同步修正:
- 触发action时不需要手动构造
{type: xxx, payload: xxx}结构,直接调用action creator函数传参即可 - 请求头字段拼写错误:
comtent-Type应为Content-Type registerSuccess里多解构了一层payload,会导致取值为空
- 触发action时不需要手动构造
修复后代码
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
相关产品推荐
相关产品推荐

