每次刷新页面时,我的localStorage PET值都会变成空字符串.我使用的是react 和打字SWC(VITE).我被困住了,不知道出了什么问题.请帮帮忙,谢谢!

import { useState, useEffect } from "react";
import petImage from "./assets/kungfudie.gif";

function App(): JSX.Element {
    const [petName, setPetName] = useState<string>("");

    //get data from localStorage on every render
    useEffect(() => {
        const name = localStorage.getItem("PET");
        if (name) {
            setPetName(JSON.parse(name));
        }
    }, []);

    //set localStorage when petName change
    useEffect(() => {
        localStorage.setItem("PET", JSON.stringify(petName));
    }, [petName]);

    return (
        <div className="bg-gray-900 text-gray-100 text-center p-5">
            <h1 className="mb-5">My Pet</h1>
            <input
                placeholder="Set Pet Name"
                value={petName}
                type="text"
                name="petName"
                id="petName"
                onChange={(e) => setPetName(e.target.value)}
            />
            <h1 className="my-5">
                {petName.length > 0 ? `Hi I'm ${petName}` : "Give me a name"}
            </h1>
            <div>
                <img style={{ maxWidth: 500 }} src={petImage} alt="Pet Image" />
            </div>
        </div>
    );
}

export default App;

推荐答案

每次刷新页面时,localStorage PET值变为空字符串的原因是,在第一次呈现时,petName初始化为空字符串:

const [petName, setPetName] = useState<string>("");

然后,一旦挂载了组件,您就可以从localStorage获得值(如果有),并使用setPetName函数将其设置为petName变量:

 //get data from localStorage on every render
  useEffect(() => {
    const name = localStorage.getItem('PET')
    if (name) {
      setPetName(JSON.parse(name))
    }
  }, [])

在此之后,您将声明另一个useEffect钩子,该钩子在每次petName个变量更改时触发:

//set localStorage when petName change
  useEffect(() => {
    localStorage.setItem('PET', JSON.stringify(petName))
  }, [petName])

这是在第一次渲染时将PET作为空字符串设置为localStorage的钩子. 原因是,在第一次呈现时,到React触发此挂接时,petName变量的值仍然是一个空字符串,因为Reaction尚未将在前一个挂接内进行的更新应用到petName:

//get data from localStorage on every render
  useEffect(() => {
    const name = localStorage.getItem('PET')
    if (name) {
      setPetName(JSON.parse(name))
    }
  }, [])

要防止这种错误行为,并在第一次渲染时使用localStorage中的值初始化petName,需要:

  1. 删除此useEffect挂钩:
 //get data from localStorage on every render
 useEffect(() => {
   const name = localStorage.getItem('PET')
   if (name) {
     setPetName(JSON.parse(name))
   }
 }, [])
  1. 使用返回值的函数将初始化从localStorage移到useState
const [petName, setPetName] = useState<string>(
   () => JSON.parse(localStorage.getItem('PET')) || ''
 )

Reactjs相关问答推荐

InfiniteScroll持续获取数据,直到超过最大更新深度

如何使用mui为可重复使用的react 按钮应用不同的风格

如何使用React Router创建响应式主详细信息应用程序?

404使用GitHub操作部署Next.js应用程序时出错

防止在Reaction中卸载

React中的useEffect钩子

有没有可能在next.js和ssr中使用tsps?

无法在下一个标头上使用 React hooks

React-dom 的钩子调用无效.我能做些什么?

React Router v6 路径中的符号

运行 npm run build 出现问题

react-router v6 中的 BrowserRouter 和 createBrowserRouter 有什么区别?我可以在不使用数据 API 的情况下使用 createBrowserRouter 吗?

如何从 graphql/apollo 中的缓存中清除多个查询

ReactJS:useMemo 钩子修复了我的无限重新渲染问题而不是 useEffect

为什么此代码中的 useState 不更新(文本更新但 id 不更新)?

无法有条件地更新useEffect中的setState

单击按钮时获取react 表中每一行的属性

如何将本地视频文件上传到 Google Cloud

由于另一个子组件,如何在react 中渲染另一个子组件

可以'读取未定义的属性(读取'路径')