skip to Main Content
 const [todo, setTodo] = useState("")
 const [todos, setTodos] = useState([])

useEffect(() => {
  let todoString =localStorage.getItem("todos")
  //this will run when todos will not be null
  if( todoString){
  let todos= JSON.parse(localStorage.getItem("todos"))
setTodos(todos)

  }
}, [])




 const saveToLS=(params) => {
   localStorage.setItem("todos", JSON.stringify(todos))
   console.log(todos)
 }
 
  const handleEdit=(e, id)=>{
   let t= todos.filter(i=> i.id === id)
setTodo(t[0].todo)

let newTodos=todos.filter(item=>{
  return item.id!==id
})
setTodos(newTodos)
saveToLS() 
  }

  const handleDelete=(e, id)=>{

let newTodos=todos.filter(item=>{
  return item.id!==id
})
setTodos(newTodos)
saveToLS()
  }

  const handleChange=(e)=>{
setTodo(e.target.value)
  }

  const handleAdd=  ()=>{
   
   setTodos([...todos, { id:uuidv4(), todo, isCompleted:false}])

setTodo("");
saveToLS()
    
  }

const handleCheckbox= (e) => {
let id=e.target.name
let index=todos.findIndex((item)=>{
  return item.id===id
})

//...TODOS IS USED FOR MAKING  A NEW ARRAY OF TODOS AND THEN SETTODO FOR RE-RENDERING
let newTodos=[...todos];
newTodos[index].isCompleted = !newTodos[index].isCompleted;
setTodos(newTodos)

saveToLS()
}


I was expecting that this will save my all todo to todos list , but this is not storing just the last entered todo , and saving first todo when i have entered the second todo, here is how I am handling changement in the state todos and todo.
this is saving (let say you give 8 todos , it will save only 7 and not 8th one )

2

Answers


  1. You are accessing the current state value inside saveToLS. state updates cause by setState reflect after the render cycle. So the value will be older.

    Send the newTodos to saveToLS.

     const saveToLS=(newTodos) => {
       localStorage.setItem("todos", JSON.stringify(newTodos))
     }
    
    Login or Signup to reply.
  2. I’d suggest that you change some of your logic.

    1. Set the inital state of todos when calling useState by immediately reading the value from your Local Storage. This way you don’t have to wait for the first render to get the initial state.
    2. Update your Local Storage when todos changes. This ensures that the Local Storage is always in sync after a state change without having to "save" manually.

    You could write this functionality as a hook, which would look something like this:

    const useLocalStorage = (storageKey, defaultValue = null) => {
      const [storage, setStorage] = useState(() => {
        const storedData = localStorage.getItem(storageKey);
        if (storedData === null) {
          return defaultValue;
        }
    
        try {
          const parsedStoredData = JSON.parse(storedData);
          return parsedStoredData;
        } catch(error) {
          console.error(error);
          return defaultValue;
        }
      });
    
      useEffect(() => {
        localStorage.setItem(storageKey, JSON.stringify(storage));
      }, [storage]);
    
      return [storage, setStorage];
    };
    

    And you’ll use it like this:

    const [todos, setTodos] = useLocalStorage('todos', []);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search