首页 > 解决方案 > 基本反应:为什么本地存储中的变量在短暂成为所需值后重置为未定义?

问题描述

我是 React 新手,正在编写一些玩具代码,其期望行为是允许用户在表单中输入他们的姓名,提交后页面将显示“Hello {user's name}”。

但是,观察到的行为是页面短暂闪烁以呈现“Hello {user's name}”,然后返回默认呈现,就好像没有提交任何名称一样。

我目前的方法是在提交时使用 useEffect 将用户名保存在本地存储中。但是,从观察控制台日志来看,本地存储似乎在将“名称”变量设置为输入的名称后立即将其重置为未定义。下面是代码。

function NameForm() {
  const [name, setName] = useState(window.localStorage.getItem("name") || "");
  useEffect(() => {
    setName(window.localStorage.setItem("name", name));
    console.log(name);
  }, [name]);
  return (
    <>
      <form
        onSubmit={event => {
          event.preventDefault();
          setName(event.target.elements.usernameInput.value);
          return false;
        }}
      >
        <label>Enter your name</label>
        <input id="usernameInput" />
        <button type="submit"> Submit</button>
      </form>
      <h1>Hello {name}</h1>
    </>
  );
}
export default function App() {
  return (
    <div className="App">
      <NameForm />
    </div>
  );
}

这里也是用于运行代码的代码框。https://codesandbox.io/s/modern-hill-gfkrp?file=/src/App.js:76-773

为什么会发生这种意外行为,我该如何解决?

谢谢!

标签: javascriptreactjslocal-storage

解决方案


为什么意外行为 window.localStorage.setItem("name", name)返回未定义。所以你本质上是setName(undefined)在你的 useEffect 中做的。因此问题。

怎么修? 您可以通过多种方式进行修复。一种方法是简单地摆脱您的 useEffect 并执行 localStorage.setItem ,onSubmit然后立即执行 setName 。

更新了代码框链接

<>
      <form
        onSubmit={event => {
          event.preventDefault();
          window.localStorage.setItem(
            "name",
            event.target.elements.usernameInput.value
          );
          setName(event.target.elements.usernameInput.value);
        }}
      >
        <label>Enter your name</label>
        <input id="usernameInput" />
        <button type="submit"> Submit</button>
      </form>
      <h1>Hello {name}</h1>
    </>

您可以通过受控输入解决您的问题。


推荐阅读