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

React首页因useEffect刷新丢失Redux数据,求解决方案

解决Redux状态获取时的组件刷新与无限渲染问题

你的问题核心在于错误的useEffect依赖配置和冗余的本地状态同步,以下是具体修复方案:

问题根源

  1. 依赖项错误:把checkUser函数放进useEffect依赖数组,而connect包装后的action函数每次组件渲染都会生成新引用,导致useEffect反复触发,不断调用checkUser,进而引发Redux状态异常和组件频繁刷新。
  2. 冗余本地状态:维护loggedIn本地状态同步Redux的isLoggedIn完全没必要——Redux状态更新本身会触发组件重新渲染,额外同步反而容易导致状态不一致。
  3. 菜单切换逻辑隐患:全局变量menuOpened会在组件重渲染时被重置为false,导致菜单切换功能失效。

修复后的完整代码

import React, { useEffect, useRef } from 'react';
import { Link } from 'react-router-dom';
import { checkUser } from '../../actions/userActions';
import { connect } from 'react-redux';
import './main.css';

function Main(props) {
    // 用useRef保存菜单状态,避免组件重渲染时被重置
    const menuOpened = useRef(false);

    // 仅在组件挂载时调用一次checkUser
    useEffect(() => {
        props.checkUser();
    }, []); // 空依赖数组确保只执行一次

    const menuToggle = (element) => {
        element.preventDefault();
        const menuButton = document.querySelector('.menu-btn');
        const responsiveMenu = document.querySelector('.toggle-menu');

        if (!menuOpened.current) {
            menuButton.classList.add('open');
            responsiveMenu?.classList.add('opened');
        } else {
            menuButton.classList.remove('open');
            responsiveMenu?.classList.remove('opened');
        }
        menuOpened.current = !menuOpened.current;
    };

    const search = (e) => {
        e.preventDefault();
    };

    // 直接从props获取Redux中的登录状态
    const isLoggedIn = props?.user?.isLoggedIn || false;

    return (
        <div>
            <h1 id='Title'>Your favorite<br></br>Gifts shop</h1>
        
            <nav id='navbar'>
                <div className='menu-btn' onClick={menuToggle}>
                    <div className='menu-btn-burger'></div>
                </div>
                <ul className='toggle-menu'>
                    <li className="toggle-menu-items">
                        <Link className='toggle-menu-anchors' to={isLoggedIn ? '/user-profile' : '/user-form'}>Profile</Link>
                    </li>
                    <li className="toggle-menu-items">
                        <Link className='toggle-menu-anchors' to='/cart'>Cart</Link>
                    </li>
                    <li className="toggle-menu-items">
                        <Link className='toggle-menu-anchors' to='/support'>Support</Link>
                    </li>
                </ul>
                <ul>
                    <li className='menu' id='menu1'><Link className='anchor-menu' to={isLoggedIn ? '/user-profile' : '/user-form'}>Profile</Link></li>
                    <li className='menu' id='menu2'><Link className='anchor-menu' to='/cart'>Cart</Link></li>
                    <li className='menu' id='menu3'><Link className='anchor-menu' to='/support'>Support</Link></li>
                </ul>
                <form id='mainForm'>
                    <input id='mainInput'/>
                    <button id='search' onClick={search}>search</button>
                </form>
            </nav>
        </div>
    );
}

const mapUserStateToProps = (state) => {
    return {
        user: state?.myUser || {} // 用户状态是单个对象,替换原数组默认值
    };
};

export default connect(mapUserStateToProps, { checkUser })(Main);

关键修复说明

  1. 移除冗余本地状态:直接使用props.user.isLoggedIn,Redux状态更新后组件会自动重新渲染,展示最新登录状态,无需额外同步。
  2. 修正useEffect调用时机:空依赖数组确保checkUser只在组件首次挂载时执行一次,既避免无限渲染,又能完成用户状态初始化。
  3. 修复菜单切换逻辑:用useRef保存menuOpened状态,其值不会随组件重渲染重置,保证菜单切换功能稳定。
  4. 优化状态映射:用户状态应为对象而非数组,调整mapUserStateToProps的默认值更合理。

修改后组件既不会无限渲染,也能实时获取Redux中的用户状态,无需额外刷新操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 21:45:34