LocalStorage保存了我的数据,但是刷新重置后将其清空

发布于 2025-01-23 04:12:10 字数 4591 浏览 2 评论 0原文

我有问题,我需要您帮助我理解它。我正在使用ReactJS,并且正在构建一个简单的Crud Todo应用程序。我想将我的戒酒存储在本地存储中。 数据保存在那里,我可以看到它,但是刷新后,它将清空我的本地存储。

我在做什么错? 我注意到的是,从我第一次打开应用程序(第一次渲染)时,本地存储在不添加todo的情况下创建存储空间。

我可以错过我的代码中的一些东西,以使其重置或在渲染页面时将其清空?

import React, { useState, useEffect } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faCheck,
  faPen,
  faPlus,
  faTrashCan,
} from "@fortawesome/free-solid-svg-icons";
import "./App.css";
import { faCircleCheck } from "@fortawesome/free-regular-svg-icons";

function App() {
  const [todos, setTodos] = useState([]);
  const [todo, setTodo] = useState("");

  const [todoEditing, setTodoEditing] = useState(null);
  const [editingText, setEditingText] = useState("");

  useEffect(() => {
    const json = window.localStorage.getItem("todos");
    const loadedTodos = JSON.parse(json);
    if (loadedTodos) {
      setTodos(loadedTodos);
    }
  }, []);

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

  function handleSubmit(e) {
    e.preventDefault();

    const newTodo = {
      id: new Date().getTime(),
      text: todo,
      completed: false,
    };

    setTodos([...todos].concat(newTodo));
    setTodo("");
  }

  function deleteTodo(id) {
    const updatedTodos = [...todos].filter((todo) => todo.id !== id);
    setTodos(updatedTodos);
  }

  function toggleComplete(id) {
    let updatedTodos = [...todos].map((todo) => {
      if (todo.id === id) {
        todo.completed = !todo.completed;
      }
      return todo;
    });
    setTodos(updatedTodos);
  }

  function submitEdits(id) {
    const updatedTodos = [...todos].map((todo) => {
      if (todo.id === id) {
        todo.text = editingText;
      }
      return todo;
    });
    setTodos(updatedTodos);
    setTodoEditing(null);
  }

  return (
    <div className="App">
      <div className="app-container">
        <div className="todo-header">
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              name="todo-input-text"
              placeholder="write a todo..."
              onChange={(e) => {
                setTodo(e.target.value);
              }}
              value={todo}
            />
            <button>
              <FontAwesomeIcon icon={faPlus} />
            </button>
          </form>
        </div>
        <div className="todo-body">
          {todos.map((todo) => {
            return (
              <div className="todo-wrapper" key={todo.id}>
                {todo.id === todoEditing ? (
                  <input
                    className="edited-todo"
                    type="text"
                    onChange={(e) => setEditingText(e.target.value)}
                  />
                ) : (
                  <p className={todo.completed ? "completed" : "uncompleted"}>
                    {todo.text}
                  </p>
                )}
                <div className="todo-buttons-wrapper">
                  <button onClick={() => toggleComplete(todo.id)}>
                    <FontAwesomeIcon icon={faCircleCheck} />
                  </button>
                  {todo.id === todoEditing ? (
                    <button onClick={() => submitEdits(todo.id)}>
                      <FontAwesomeIcon icon={faCheck} />
                    </button>
                  ) : (
                    <button onClick={() => setTodoEditing(todo.id)}>
                      <FontAwesomeIcon icon={faPen} />
                    </button>
                  )}
                  <button
                    onClick={() => {
                      deleteTodo(todo.id);
                    }}
                  >
                    <FontAwesomeIcon icon={faTrashCan} />
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

export default App;

”我添加一个todo

I have a problem and I need you to help me understand it. I am using ReactJS and I am building a simple CRUD Todo App. I Want to store my todos in local storage.
The data is saved there and I can see it but after the refresh it is emptying my local storage.

What am I doing wrong?
Something that I notice is that from the first time when I open the app (first rendering), local storage is creating the storage space without adding a todo.

Could I have missed something in my code that makes it reset it or empty it when the page is rendered?

import React, { useState, useEffect } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
  faCheck,
  faPen,
  faPlus,
  faTrashCan,
} from "@fortawesome/free-solid-svg-icons";
import "./App.css";
import { faCircleCheck } from "@fortawesome/free-regular-svg-icons";

function App() {
  const [todos, setTodos] = useState([]);
  const [todo, setTodo] = useState("");

  const [todoEditing, setTodoEditing] = useState(null);
  const [editingText, setEditingText] = useState("");

  useEffect(() => {
    const json = window.localStorage.getItem("todos");
    const loadedTodos = JSON.parse(json);
    if (loadedTodos) {
      setTodos(loadedTodos);
    }
  }, []);

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

  function handleSubmit(e) {
    e.preventDefault();

    const newTodo = {
      id: new Date().getTime(),
      text: todo,
      completed: false,
    };

    setTodos([...todos].concat(newTodo));
    setTodo("");
  }

  function deleteTodo(id) {
    const updatedTodos = [...todos].filter((todo) => todo.id !== id);
    setTodos(updatedTodos);
  }

  function toggleComplete(id) {
    let updatedTodos = [...todos].map((todo) => {
      if (todo.id === id) {
        todo.completed = !todo.completed;
      }
      return todo;
    });
    setTodos(updatedTodos);
  }

  function submitEdits(id) {
    const updatedTodos = [...todos].map((todo) => {
      if (todo.id === id) {
        todo.text = editingText;
      }
      return todo;
    });
    setTodos(updatedTodos);
    setTodoEditing(null);
  }

  return (
    <div className="App">
      <div className="app-container">
        <div className="todo-header">
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              name="todo-input-text"
              placeholder="write a todo..."
              onChange={(e) => {
                setTodo(e.target.value);
              }}
              value={todo}
            />
            <button>
              <FontAwesomeIcon icon={faPlus} />
            </button>
          </form>
        </div>
        <div className="todo-body">
          {todos.map((todo) => {
            return (
              <div className="todo-wrapper" key={todo.id}>
                {todo.id === todoEditing ? (
                  <input
                    className="edited-todo"
                    type="text"
                    onChange={(e) => setEditingText(e.target.value)}
                  />
                ) : (
                  <p className={todo.completed ? "completed" : "uncompleted"}>
                    {todo.text}
                  </p>
                )}
                <div className="todo-buttons-wrapper">
                  <button onClick={() => toggleComplete(todo.id)}>
                    <FontAwesomeIcon icon={faCircleCheck} />
                  </button>
                  {todo.id === todoEditing ? (
                    <button onClick={() => submitEdits(todo.id)}>
                      <FontAwesomeIcon icon={faCheck} />
                    </button>
                  ) : (
                    <button onClick={() => setTodoEditing(todo.id)}>
                      <FontAwesomeIcon icon={faPen} />
                    </button>
                  )}
                  <button
                    onClick={() => {
                      deleteTodo(todo.id);
                    }}
                  >
                    <FontAwesomeIcon icon={faTrashCan} />
                  </button>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

export default App;

from the first render is allocating the space

after I add a todo ass you can see is saving it to my local storage but after the refresh is empty just like in the first image

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

巴黎夜雨 2025-01-30 04:12:10

如果像这样在localstorage中可用,则应从localstorage上加载dodos,

const loadedTodos = localStorage.getItem("todos")
  ? JSON.parse(localStorage.getItem("todos"))
  : []; // new

const [todos, setTodos] = useState(loadedTodos); // updated

然后您不必在useffect中使用settodos(ladeedtodos)突变状态。

只需从代码中删除此使用效果:

// that useEffect should be removed
useEffect(() => {
    const json = window.localStorage.getItem("todos");
    const loadedTodos = JSON.parse(json);
    if (loadedTodos) {
      setTodos(loadedTodos);
    }
  }, []);

您可以在工作 codesandbox 也是如此。

You should be loading todos from localStorage on the Component mount if they are available in localStorage like this,

const loadedTodos = localStorage.getItem("todos")
  ? JSON.parse(localStorage.getItem("todos"))
  : []; // new

const [todos, setTodos] = useState(loadedTodos); // updated

And then you don't have to mutate the state using setTodos(loadedTodos) in the useEffect.

Just remove this useEffect , from the code:

// that useEffect should be removed
useEffect(() => {
    const json = window.localStorage.getItem("todos");
    const loadedTodos = JSON.parse(json);
    if (loadedTodos) {
      setTodos(loadedTodos);
    }
  }, []);

You can check this in the working CodeSandbox as well.

萌吟 2025-01-30 04:12:10

我认为您的第二次使用效果使其重置。

将使用效果逻辑移动到单独的函数。

而不是调用settodos,请调用该功能,更新存储,然后从该功能调用settodos

I think your second useEffect is causing it to reset.

Move that the useEffect logic to a separate function.

And instead of calling setTodos, call that function, update the storage, and then call setTodos from that function.

柒夜笙歌凉 2025-01-30 04:12:10

如果您使用回调函数调用Settodos函数,并将其类似的传播操作员起作用:

useEffect(() => {
const json = window.localStorage.getItem("todos");
const loadedTodos = JSON.parse(json);
if (loadedTodos) {
// set local storage like this
  setTodos( prevTodos => [...prevTodos, ...loadedTodos] ); 
}}, []);

If you call the setTodos function with a callback function and spread operator like this it should work:

useEffect(() => {
const json = window.localStorage.getItem("todos");
const loadedTodos = JSON.parse(json);
if (loadedTodos) {
// set local storage like this
  setTodos( prevTodos => [...prevTodos, ...loadedTodos] ); 
}}, []);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文