ReactJS 中 localstorage 设置值的问题

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

我正在尝试将值保存在本地存储中。当我单击“设置项目”时,它第一次在本地存储上保存一个空数组。之后这段代码就可以正常工作了。我是反应和TS的初学者。这是下面的代码。

hooks/useLocalStorage.ts

function useLocalStorage(key: string) {
  /* Set Item to Localstorage */
  const set = (value: unknown) => {
    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.log((error as Error)?.message);
    }
  };

  /* Get Item from Localstorage */
  const get = () => {
    try {
      return localStorage.getItem(key);
    } catch (error) {
      console.log(error);
    }
  };

  /* Remove Item */
  const clean = () => {
    try {
      localStorage.removeItem(key);
    } catch (error) {
      console.log((error as Error)?.message);
    }
  };

  return { set, get, clean };
}

export { useLocalStorage };

App.tsx

import { Button, ButtonGroup, TextField } from "@mui/material";
import { useState } from "react";
import { useLocalStorage } from "./hooks/useLocalStorage";

function App() {
  type TProp = {
    title: string;
  };

  const [value, setValue] = useState("");
  const { set, get, clean } = useLocalStorage("todos");
  const [todos, setTodos] = useState<TProp[]>([]);

  /* Set Item */
  const setItem = () => {
    setTodos([...todos, { title: value }]);
    set(todos);
  };

  return (
    <>
      <TextField
        label="Enter Text"
        variant="outlined"
        fullWidth
        margin="normal"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <ButtonGroup variant="contained" fullWidth>
        <Button onClick={setItem}>Set Item</Button>
        <Button color="success" onClick={() => console.log(get())}>
          Get Item
        </Button>
      </ButtonGroup>
      <Button
        variant="contained"
        color="error"
        fullWidth
        sx={{ mt: 2 }}
        onClick={clean}
      >
        Remove Item
      </Button>
    </>
  );
}

export default App;

main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

我尝试记录来自 useLocalStorage 和 App.tsx 的值。

使用 useEffect 钩子创建一个具有相同名称的空数组,但未进行 wprked。

App.tsx

/** ... **/

useEffect(() => {
  if(get()?.length === 0) {
    /* todos is empty at this moment */
    set(todos)
  }
},[])

/** ... **/

上面的代码工作完美,正如预期的那样,它在本地存储中创建了一个名为 todos 的空数组,但如果我在输入上添加一些值并第一次单击 Set ,它仍然不起作用。

javascript reactjs typescript react-hooks local-storage
1个回答
0
投票

由于 react

setState
是异步的,[github] 你不会在
todos
之后立即获得更新的
setTodos([...todos, { title: value }])
,所以不要依赖
todos
set(todos)
触发时保持最新状态.

我建议创建一个临时的事实来源,

setTodos
set
都可以从中获得他们的论点。

因此:

const setItem = () => {
  let __temp = [...todos, { title: value }]; 
  setTodos(__temp);
  set(__temp); /* <—- I no longer depend on setTodos updating todos because I now have my own source of truth. */
};
© www.soinside.com 2019 - 2024. All rights reserved.