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

MERN栈Redux实现登录时获取userInfo报TypeError问题

MERN栈Redux登录功能报错排查

问题描述

我是编程新手,近期学习使用MERN栈开发用户注册登录功能,后端功能运行无异常,但在前端集成Redux时抛出TypeError报错,报错参考截图:
Redux集成报错截图
我已确认Redux store正确关联了reducer、action与常量文件,期望实现将后端返回的登录数据存入userInfo的功能,使用的是最新版本Redux,暂未定位到代码错误。

问题相关代码

SignInScreen.js 登录页组件代码

import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { login } from '../actions/userAction'

export const SignInScreen = (props, history) => {
  const navigate = useNavigate
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')
  const submitHandler = (e) => {
    e.preventDefault()
    dispatch(login(email, password))
  }
  const { search } = useLocation()
  const redirectInUrl = new URLSearchParams(search).get('redirect')
  const redirect = redirectInUrl ? redirectInUrl : '/'

  const userlogin = useSelector((state) => state.userlogin)
  const { userInfo, loading, error } = userlogin
  const dispatch = useDispatch()

  useEffect(() => {
    if (userInfo) {
      navigate(redirect)
    }
  }, [navigate, userInfo, redirect])

store.js Redux配置代码

import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'

import {
  userLoginReducer,
} from './reducers/userReducer'


const userInfo = localStorage.getItem('userInfo')
  ? JSON.parse(localStorage.getItem('userInfo'))
  : null

const initialState = {
  userLogin: { userInfo },
}
const reducer = combineReducers({
  userLogin: userLoginReducer,
})

const middleware = [thunk]

const store = createStore(
  reducer,
  initialState,
  compose(applyMiddleware(...middleware))
)
export default store

Redux常量定义代码

export const USER_LOGIN_REQUEST = 'USER_LOGIN_REQUEST'
export const USER_LOGIN_SUCCESS = 'USER_LOGIN_SUCCESS'
export const USER_LOGIN_FAIL = 'USER_LOGIN_FAIL'

export const USER_LOGOUT = 'USER_LOGOUT'

userReducer.js 登录状态Reducer代码

import {
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
  USER_LOGIN_FAIL,
  USER_LOGOUT,
} from '../constants/userConstant'

function userLoginReducer(state = {}, action) {
  switch (action.type) {
    case USER_LOGIN_REQUEST:
      return { loading: true }
    case USER_LOGIN_SUCCESS:
      return { loading: false, userInfo: action.payload }
    case USER_LOGIN_FAIL:
      return { loading: false, error: action.payload }
    case USER_LOGOUT:
      return {}
    default:
      return state
  }
}

export userLoginReducer

userAction.js 登录逻辑Action代码

import Axios from 'axios'
import {
  USER_LOGIN_REQUEST,
  USER_LOGIN_SUCCESS,
  USER_LOGIN_FAIL,
} from '../constants/userConstant'


const login = (email, password) => async (dispatch) => {
  try {
    dispatch({ type: USER_LOGIN_REQUEST })
    const config = { headers: { 'Content-Type': 'application/json' } }
    const { data } = await Axios.post(
      '/api/users/login',
      { email, password },
      config
    )
    dispatch({ type: USER_LOGIN_SUCCESS, payload: data })
    localStorage.setItem('userInfo', JSON.stringify(data))
  } catch (error) {
    dispatch({
      type: USER_LOGIN_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}

export login

错误点与修复方案

代码中一共存在5处直接导致报错的问题,按优先级修复即可:

    1. Redux状态读取键名大小写不匹配
      store中通过combineReducers注册的登录状态键名为userLogin(驼峰写法,L大写),但组件中useSelector读取时写的是state.userlogin(l小写),Redux状态匹配严格区分大小写,该写法会直接取到undefined,后续解构userInfo时就会抛出TypeError。
      修复:将useSelector部分代码修改为
    const userLogin = useSelector((state) => state.userLogin)
    const { userInfo, loading, error } = userLogin
    
    1. useNavigate Hook调用方式错误
      代码中写为const navigate = useNavigate,仅将Hook本身赋值给变量,没有执行Hook拿到导航方法,后续调用navigate(redirect)时会触发"not a function"报错。
      修复:修改为const navigate = useNavigate()
    1. Hook声明顺序违规
      代码中先在submitHandler函数内调用了dispatch,之后才声明const dispatch = useDispatch(),违反React Hook"必须在组件顶层、所有业务逻辑之前声明"的规则,同时会触发暂存死区错误。
      修复:将const dispatch = useDispatch()移动到组件最顶部,和其他Hook(useState、useNavigate等)同层级,放在submitHandler定义之前。
    1. ES模块导出语法错误
      userReducer.js中export userLoginReducer、userAction.js中export login均为非法语法,ES模块导出不支持直接写export 变量名的格式,会导致模块导入失败。
      修复:
    • userReducer.js最后一行修改为export { userLoginReducer }(和store中的具名导入写法匹配)
    • userAction.js中login函数声明修改为export const login = (email, password) => async (dispatch) => {,删除文件最后单独的export login行
    1. 组件代码不完整
      当前贴出的SignInScreen.js没有写return返回JSX的部分,也没有闭合组件函数的大括号,会触发语法错误,记得补全表单渲染的JSX代码和函数闭合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 09:03:50