简体   繁体   中英

Adding Item to LocalStorage then retrieving it using useState() REACT

I'm very new to react so please bare with me. I am creating a simple toDo list react application using localstorage. I have InputTask component that keeps track of the input box state (where the user enters the task they want to add).

My goal right now is to add the task the user enters to localstorage then using another state called tasks update all tasks to contain the new task the user entered. I feel like i'm overcomplicating this please help.

import React, { useEffect, useState } from "react";

// Imported Components below
import CurrentTasks from "./CurrentTasks";

function InputTask() {
  // Initial array for storing list items
  // Tracking state of input box
  const [task, setTask] = useState();
  const [tasks, setTasks] = useState([]);

  function handleAddTask() {
    // Create array to add to local storage of tasks
    let allTasks = [];
    // push new task to array
    allTasks.push(task);
    // add task to localstorage
    localStorage.setItem("tasks", JSON.stringify(allTasks));
    // update setTasks with new task (This contains all tasks prev)
    setTasks(JSON.parse(localStorage.getItem("tasks")));
  }

  return (
    <div className="container">
      <div className="input-group mt-4">
        <input
          onChange={e => setTask(e.target.value)}
          type="text"
          className="form-control form-control-lg"
          placeholder="Write task here..."
        />
        <div className="input-group-append">
          <button onClick={handleAddTask} className="btn btn-outline-secondary">
            Add
          </button>
        </div>
      </div>
      <CurrentTasks />
    </div>
  );
}

export default InputTask;

The issue I am running into is that the tasks state is always behind. So if i were to add "Make bed" to the task as the first item "Make bed" would not appear until I enter in a new task such as "fold cloths". Then, "fold cloths" will not appear until I enter in a new task... ect..

在此处输入图片说明

Per my comment above, localStorage doesn't guarantee that it's done writing to disk before continuing JS execution. But that's okay, since what you really want to do is get the persisted tasks ONCE when the component renders, and only persist the new set of tasks very rarely (on unmount, once a minute, etc.).

The best way to structure this code would probably be:

  1. On first render, get the stored tasks from localStorage and put it in a variable
  2. On submit, simply append your new task to that variable
  3. At an appropriate time (unmount, or periodically), persist the whole thing to localStorage again.
function InputTask() {
  const [task, setTask] = useState();
  // Get the persisted tasks ONLY on first render
  const [tasks, setTasks] = useState(JSON.parse(localStorage.getItem("tasks") || "[]"));

  function handleAddTask() {
    // Just set tasks to tasks + task
    setTasks([...tasks, task]);
    // And probably clear the input
    setTask(""); 
  }

  // Serialize all tasks on unmount
  // (Just for illustration, you may want to do it more often than this)
  useEffect(() => {
    return () => localStorage.setItem("tasks", JSON.stringify(tasks));
  }, []);
  ...
}

You should update the state directly insted of a seperate array.

Push method in React Hooks (useState)?

Then you should use onChange to update localstorage

https://www.robinwieruch.de/local-storage-react

tasks length will always be one in your case. Isn't it? I guess handleAddTask() should be like this.

function handleAddTask() {
    // Create array to add to local storage of tasks
    let allTasks = JSON.parse(localStorage.getItem("tasks"));
    allTasks.push(task);
    localStorage.setItem("tasks", JSON.stringify(allTasks));
    setTasks(allTasks);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM