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

为什么从Local Storage获取新值时,带条件运算符的className不更新?

问题:LocalStorage 更新后组件未重新渲染

我把菜单展开状态存在 LocalStorage 里,写了getItem和setItem操作函数,还实现了自定义 Hook useMenu管理状态,但点击触发toggleMenu后,LocalStorage 里的值明明已经更新,菜单的 className 却没变化,组件也完全不重新渲染。

相关代码如下:

自定义 Hook 实现

const getItem = (key, defaultValue) => {
    // 获取项,若为undefined/null则返回默认值
};

const setItem = (key, value) => {
    // 设置项,功能正常
};

export const useMenu = () => {
    const isOpened = Boolean(getItem("isOpened", true));
    const toggleMenu = useCallback(() => {
        setItem("isOpened", !isOpened);
    }, [isOpened]);
    
    // ...

    return {
        isOpened,
        toggleMenu,
    };
};

组件中使用

const { isOpened, toggleMenu } = useMenu();
<div className={isOpened ? styles.openedContainer : styles.closedContainer}>

原因分析

isOpened是直接从 LocalStorage 读取的普通变量,不是 React 的状态变量(比如useState返回的状态)。React 只有在状态或 props 变化时才会触发组件重渲染,所以哪怕 LocalStorage 里的值变了,isOpened也不会自动更新,组件自然不会重新渲染。


解决方案

用useState来管理isOpened状态,初始化时从 LocalStorage 取值,同时在toggleMenu里同步更新状态和 LocalStorage:

修正后的useMenu Hook

const getItem = (key, defaultValue) => {
    const storedValue = localStorage.getItem(key);
    return storedValue !== null ? JSON.parse(storedValue) : defaultValue;
};

const setItem = (key, value) => {
    localStorage.setItem(key, JSON.stringify(value));
};

export const useMenu = () => {
    // 初始化时从LocalStorage取状态,初始化函数仅执行一次
    const [isOpened, setIsOpened] = useState(() => {
        return Boolean(getItem("isOpened", true));
    });

    const toggleMenu = useCallback(() => {
        setIsOpened(prevState => {
            const newState = !prevState;
            // 同步更新LocalStorage
            setItem("isOpened", newState);
            return newState;
        });
    }, []);
    
    return {
        isOpened,
        toggleMenu,
    };
};

关键改动说明

  • 用useState定义isOpened状态,确保状态变化能触发组件重渲染
  • 采用函数式更新setIsOpened,避免依赖外部isOpened变量,同时保证获取到最新的状态值
  • useCallback依赖数组为空,减少不必要的回调重新创建

修改后,点击触发toggleMenu时,isOpened状态会更新,React 会自动触发组件重渲染,菜单的 className 也会随之切换,LocalStorage 的值也能保持同步。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:10:13