React useState 和 useEffect 未使用 localStorage 正确更新状态

问题描述 投票:0回答:1

我遇到了一个 React 组件的问题,该组件利用 useState 和 useEffect 挂钩来管理状态并将其保留在 localStorage 中。该组件旨在创建一个带有标题和内容的可切换部分,其中展开状态存储在 localStorage 中。但是,我遇到了状态未正确更新的困难,尤其是在页面刷新之后。

这是该组件的代码:

const ToggleSection = ({ title, children }) => {
  const [expanded, setExpanded] = useState(false);

  useEffect(() => {
    const storedState = localStorage.getItem(`toggleSection_is_toggled_${title.replace(' ', '_')}`);

    if (storedState !== null) {
      setExpanded(storedState === 'true');
    }
  }, [title]);

  useEffect(() => {
    localStorage.setItem(`toggleSection_is_toggled_${title.replace(' ', '_')}`, expanded.toString());
  }, [expanded, title]);

  const toggleExpanded = () => {
    setExpanded(!expanded);
  };

  useEffect(() => {
    console.log("Updated Expanded:", expanded);
  }, [expanded]);

  console.log("Render Expanded:", expanded);

  return (
    <div className={Styles['toggle-section']}>
      <div className={Styles['toggle-header']} onClick={toggleExpanded}>
        <h2 className={Styles['toggle-title']}>{title}</h2>
        <span className={Styles['toggle-icon']}>{expanded ? '−' : '+'}</span>
      </div>
      {expanded && <div className={Styles['toggle-content']}>{children}</div>}
    </div>
  );
};


I expect the component to correctly update its state based on the value retrieved from localStorage and reflect those changes in the UI. However, after page refreshes, the state seems to be reset to false, even though the value in localStorage is correct.

I've tried logging the state at various points in the component, and it appears that the state is not being updated correctly after retrieving it from localStorage.

Could someone please help me understand what might be causing this issue and how I can ensure that the state is updated correctly based on the value from localStorage?
reactjs local-storage
1个回答
0
投票

这个

useEffect
钩子会立即运行:

  useEffect(() => {
    localStorage.setItem(`toggleSection_is_toggled_${title.replace(' ', '_')}`, expanded.toString());
  }, [expanded, title]);

一旦你的组件渲染,它就会看到默认的展开状态为 false,并根据该初始默认值设置本地存储值。您可以做一些事情,要么将初始状态设置为

null
,并在该钩子中设置本地存储之前检查以确保它不为空,或者创建另一个类似于
const [initialRender, setInitialRender] = useState(true)
的状态,然后在第一个
useEffect
钩子中将其设置为 false,然后检查这一点,但我真的认为最好的方法就是直接在
toggleExpanded
函数中设置由于展开状态而切换的值...这样你就知道它只会在单击某些内容时运行。

© www.soinside.com 2019 - 2024. All rights reserved.