使用本地存储在 React 中刷新页面后保持状态

persist state after page refresh in React using local storage

我希望发生的情况是单击 displayBtn() 以显示 localStorage 中的项目。

useEffect() 中有 localStorage.setItem("localValue", JSON.stringify(myLeads)) MyLeads 是一个包含潜在客户常量的数组 const [myLeads, setMyLeads] = useState([]); 当单击 saveBtn() 时,myLeads 状态会更改 setMyLeads((prev) => [...prev, leadValue.inputVal]);

在 DevTools > Applications 中,正在更新 localStorage,但刷新页面时 localStorage 为空 []。刷新后如何使 localStorage 保持状态?我遇到了这个 article 并应用了逻辑,但它没有解决问题。我知道这是我做错了什么。

import List from './components/List'
import { SaveBtn } from './components/Buttons';

function App() {
  const [myLeads, setMyLeads] = useState([]);
  const [leadValue, setLeadValue] = useState({
    inputVal: "",
  });

  const [display, setDisplay] = useState(false);

  const handleChange = (event) => {
    const { name, value } = event.target;
    setLeadValue((prev) => {
      return {
        ...prev,
        [name]: value,
      };
    });
  };

  const localStoredValue = JSON.parse(localStorage.getItem("localValue")) ;

  const [localItems] = useState(localStoredValue || []);

  useEffect(() => {
    localStorage.setItem("localValue", JSON.stringify(myLeads));
  }, [myLeads]);

  const saveBtn = () => {
    setMyLeads((prev) => [...prev, leadValue.inputVal]);
    // setLocalItems((prevItems) => [...prevItems, leadValue.inputVal]);

    setDisplay(false);
  };

  const displayBtn = () => {
    setDisplay(true);    
  };


  const displayLocalItems = localItems.map((item) => {
    return <List key={item} val={item} />;
  });

  return (
    <main>
      <input
        name="inputVal"
        value={leadValue.inputVal}
        type="text"
        onChange={handleChange}
        required
      />

      <SaveBtn saveBtn={saveBtn} />

      <button onClick={displayBtn}>Display Leads</button>

      {display && <ul>{displayLocalItems}</ul>}
    </main>
  );
}

export default App;```

您已陷入经典的 React Hooks 陷阱 - 因为使用 useState() 是如此简单,您实际上过度使用了它。

如果 localStorage 是您的存储机制,那么您根本不需要 useState()。你最终会在某个时候在你的两个消息来源之间就什么是“正确的状态”发生争执。

你的 use-case 只需要一些东西来保存为你的受控 input 组件提供的文本(我称之为 leadText),以及一些东西来保存你的 display 布尔值:

  const [leadText, setLeadText] = useState('')
  const [display, setDisplay] = useState(false)
  const localStoredValues = JSON.parse(window.localStorage.getItem('localValue') || '[]')

  const handleChange = (event) => {
    const { name, value } = event.target
    setLeadText(value)
  }

  const saveBtn = () => {
    const updatedArray = [...localStoredValues, leadText]
    localStorage.setItem('localValue', JSON.stringify(updatedArray))
    setDisplay(false)
  }

  const displayBtn = () => {
    setDisplay(true)
  }

  const displayLocalItems = localStoredValues.map((item) => {
    return <li key={item}>{item}</li>
  })

  return (
    <main>
      <input name="inputVal" value={leadText} type="text" onChange={handleChange} required />

      <button onClick={saveBtn}> Save </button>

      <button onClick={displayBtn}>Display Leads</button>

      {display && <ul>{displayLocalItems}</ul>}
    </main>
  )