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

React JS中导航栏退出按钮与购物车数量仅刷新后更新问题求助

问题原因
  • 你当前的loggedIn状态仅在Navigation组件首次挂载时读取一次localStorage取值,React的useState初始值默认仅执行一次,后续localStorage内容发生变更时,该状态不会自动同步更新,自然不会触发组件重渲染。
  • 购物车数量的计算函数getCartItems仅会在组件重渲染时重新执行,组件未触发更新的前提下,读取的永远是挂载时的旧值。
  • 附带错误:localStorage.clear()方法不接收任何参数,调用后会清空所有本地存储内容,如果你仅需删除指定字段,应该使用localStorage.removeItem()。
修复方案

你可以通过自定义事件通知的方式最小成本修复该问题,无需引入额外的全局状态管理库,修改逻辑如下:

  1. 在Navigation组件中新增状态更新逻辑,监听自定义的存储变更事件,收到事件后重新读取localStorage更新组件状态。
  2. 在登录成功、buy按钮点击加购完成、退出登录的操作逻辑末尾,手动触发该自定义事件,通知Navigation组件更新。

修改后的Navigation组件代码

import { useState, useEffect } from 'react';
import { useHistory } from 'react-router-dom';

function Navigation() {
    // 初始化登录状态、购物车数量状态
    const [loggedIn, setLoggedIn] = useState(!!JSON.parse(localStorage.getItem("games")));
    const [cartCount, setCartCount] = useState(0);
    const history = useHistory();

    // 统一更新导航栏状态的方法
    const updateNavStatus = () => {
        const gamesData = JSON.parse(localStorage.getItem("games"));
        setLoggedIn(!!gamesData);
        setCartCount(gamesData ? gamesData.length : 0);
    }

    useEffect(() => {
        // 组件挂载时初始化状态
        updateNavStatus();
        // 监听存储更新的自定义事件
        window.addEventListener('localStorageChanged', updateNavStatus);
        // 组件卸载时移除监听避免内存泄漏
        return () => window.removeEventListener('localStorageChanged', updateNavStatus);
    }, []);

    function logOut() {
        // 修正本地存储删除逻辑
        localStorage.removeItem('Email');
        localStorage.removeItem('Password');
        localStorage.removeItem('games');
        // 触发更新事件
        window.dispatchEvent(new Event('localStorageChanged'));
        history.push('/');
    }

    return (
        <div className="navgation_container">
            <div className="navigation_cartcontainer">
                <img className="navigation_logo" src={logo} alt="logog bits&bots" />
                {loggedIn ? (
                    <div className="navigation_cartimg">
                        <img className="navigation_cart" src={cart} alt="cart for the page" />
                        <p className="navigation_numberitems">{cartCount}</p>
                        <button className="navigation_logout" onClick={logOut}>Log out</button>
                    </div>
                ) : (
                    <div>Test</div>
                )}
            </div>
        </div>
    );
}

其他关联代码修改

  • 登录逻辑执行成功,写入localStorage后,添加一行代码:window.dispatchEvent(new Event('localStorageChanged'))
  • 封装的通用buy按钮组件,加购逻辑完成写入localStorage后,同样添加上述触发事件的代码即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:24:04