簡體   English   中英

LocalStorage 在提交后不顯示數據,並且 state 在刷新時不會持續存在

[英]LocalStorage doesn't display the data after submit and state doesn't persist on refresh

我正在編寫一個簡單的待辦事項應用程序並嘗試將數據保存在本地存儲中。 我看過幾個考慮在 React 中使用 localStorage 的教程,並按照他們說的一步一步做,代碼似乎還不錯。 似乎是問題所在,是本地存儲本身。 當我使用 localStorage.setItem() 添加待辦事項時,它應該會自動更新並顯示數據,但事實並非如此。 只有當我刷新它(應用程序 - > 本地存儲中控制台中帶有鍵值對的字段上方的小刷新按鈕)時,我才能看到顯示的鍵值對,所以看起來它已經工作了。 但是,即使手動刷新后似乎保留了數據,但當我刷新整個頁面時,數據消失了。 下面我包含了我的大部分代碼,也許我遺漏了一些東西,有人會注意到這個錯誤。 有人可以幫忙嗎?

const [todos, setTodos] = useState([]);

  const addTodo = (e) => {
    e.preventDefault();
    if (inputValue.trim() === "") return;
    setTodos([
      ...todos,
      {
        text: inputValue,
        id: uuidv4(),
      },
    ]);

    setInputValue("");
  };

  useEffect(() => {
    const localData = localStorage.getItem("TODO_APP");
    if (localData !== null) setTodos(JSON.parse(localData));
  }, []);

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

看起來像useEffect沖突。 將初始化移到useState調用中。

const [todos, setTodos] = useState(() => {
  const localData = localStorage.getItem("TODO_APP");
  if (localData !== null) return JSON.parse(localData);
  return [];
});

const addTodo = (e) => {
  e.preventDefault();
  if (inputValue.trim() === "") return;
  setTodos([
    ...todos,
    {
      text: inputValue,
      id: uuidv4(),
    },
  ]);

  setInputValue("");
};

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

我將添加另一個稍作修改的版本。 應該管用:

const [todos, setTodos] = useState(JSON.parse(localStorage.getItem('TODO_APP')) || []);

const addTodo = (e) => {
    e.preventDefault();
    
    if (inputValue.trim() !== '') {
        setTodos([
            ...todos,
            {
                text: inputValue,
                id: uuidv4()
            }
        ]);
    }

    setInputValue('');
};

useEffect(() => {
    localStorage.setItem('TODO_APP', JSON.stringify(todos));
}, [todos]);

其他解決方案可能對您有用,但如果您使用的是React 18 ,您的代碼非常好,問題是useEffects在刷新時調用了兩次,它正在重置 localStorage。 這是一種已知問題。

您只需要在src/index.js文件中禁用StrictMode

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);

reportWebVitals();

我嘗試完成組件的缺失部分,最終組件如下所示:

import { useState, useEffect } from "react";

const Todo = () => {
  const [todos, setTodos] = useState([]);
  const [inputValue, setInputValue] = useState("");

  const onChangeHandler = (e) => {
    setInputValue(e.target.value);
  };

  const addTodo = (e) => {
    e.preventDefault();
    if (inputValue.trim() === "") return;
    setTodos([...todos, { text: inputValue }]);

    setInputValue("");
  };

  useEffect(() => {
    console.log("1st");
    const localData = localStorage.getItem("TODO_APP");
    console.log(localData);
    if (localData.length !== 0) setTodos(JSON.parse(localData));
  }, []);

  useEffect(() => {
    console.log("2nd");
    localStorage.setItem("TODO_APP", JSON.stringify(todos));
  }, [todos]);

  return (
    <form onSubmit={addTodo}>
      <input type="text" value={inputValue} onChange={onChangeHandler}></input>
      <button type="submit">ADD TODO</button>
    </form>
  );
};

export default Todo;

我在代碼中添加了console.log() ,所以你可以觀察這些useEffects在刷新時是如何被調用的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM