When I click on the checkbox, the task should move to the completed section and be saved there even if the page is reloaded. But is not working.

import { useState,useEffect } from "react";
import Completed from "../completed/Completed";
import TodoList from "../todoList/TodoList";
import "./additems.css";

const AddItem = () => {
    const [tasks, setTasks] = useState([]);
    const [inputValue, setInputValue] = useState("");
    const [editingIndex, setEditingIndex] = useState(null);
    const [completed, setCompleted] = useState([])

    const currentDate = new Date().toLocaleString('en-US', {weekday: 'long'});

const handlerInputChange = (e) => {
      let textInp = e.target.value;
      if(textInp.length <= 70){
         setInputValue(textInp);
      } 
}    
const handlerAdd = (e) => {
      e.preventDefault();
      if(inputValue.trim() === ""){
         return;
      }
      setTasks([...tasks, inputValue + ` - ${currentDate}`])
      setInputValue("");
      setEditingIndex(tasks.length);
      
    }
const handlerDelete = (index) => {
      const newTasks = [...tasks];
      newTasks.splice(index,1)
      setTasks(newTasks);
}
const handlerCompleted = (index) => {
        const newTasks = [...tasks];
        const completedTask = newTasks.slice(index, index + 1);
        setCompleted([...completed, completedTask]);
        setTasks(newTasks.slice(0, index).concat(newTasks.slice(index + 1)));
}
const renderItems = (arr) => {
    const items = arr.map((item,index) => {
        
          if(index === editingIndex){
            return (<li key={index}
                        className="list_save">
                   <div className="date_number">
                   <p>{index + 1}</p>
                   </div>    
                <input
                maxLength={50} 
                className="task_value"
                type="text"
                defaultValue={item}
                onChange={(e) => {
                    const newTasks = [...tasks,];
                    newTasks[index] = e.target.value;
                    setTasks(newTasks);
                }}
                />
                    <button 
                           onClick={() => setEditingIndex(null)}
                           className="save_task"
                    >Save</button>

                </li>)
          }else {
            return (
                <li key={index}
                    className="list_edit">
                        <input type="checkbox" 
                               className="checkbox_completed"
                               onClick={() => handlerCompleted(index)}/>
                        <p>{item}</p>
                    <button 
                          onClick={() => setEditingIndex(index)}
                          className="edit_task"
                    >Edit</button>
                    <button 
                          onClick={() => handlerDelete(index)}
                          className="delete_task"
                    >Delete</button>
                </li>
            );
        }
    })      
    return (<ol className="items_list">
              {items}
          </ol>
       ) 
}
    const items = renderItems(tasks);
    return(<div>
                <form 
                    className="form_add"
                    onSubmit={handlerAdd}
                    >
                <input className="input_add"
                    maxLength={50} 
                    type="text"
                    value={inputValue}
                    onChange={handlerInputChange} />
                <button className="btn_add" type="submit">Add</button>
            </form>
            <TodoList task={items}/>
            <Completed completed={completed}/>
        </div>
        )
}
export default AddItem;

import { useState,useEffect } from "react";
import "./completed.css";
const Completed = (props) => {
    
    const {completed} = props
    const [completedTasks, setCompletedTasks] = useState(completed);
   
        useEffect(() => {
        const storedCompletedTasks = JSON.parse(localStorage.getItem("completedTasks")) || [];
        setCompletedTasks((prevTasks) => [...prevTasks, ...storedCompletedTasks]);
    }, []);
    useEffect(() => {
        localStorage.setItem("completedTasks", JSON.stringify(completedTasks));
    }, [completedTasks]);
    return( <div className="completed_list">
            <h3>Completed</h3>
            <div className="line_completed"></div>
            {completedTasks.map((task,index) => {
              return (<ul key={index}>
                <li>
                    {task}
                   
                </li>
              </ul>)
           })}
  </div>)
}
export default Completed;

React DevTools shows that the Completed component is filled with an array when the checkbox is clicked. However, it does not display completed tasks in the Completed component.

1

There are 1 best solutions below

0
John Detlefs On BEST ANSWER

Your useEffect is potentially overwriting the completed prop.

Try:

useEffect(() => {
  const storedCompletedTasks = JSON.parse(localStorage.getItem("completedTasks")) || [];
  setCompletedTasks((prevTasks) => [...prevTasks, ...completed, ...storedCompletedTasks]);
}, [completed]);

In this way, you're guaranteeing that completed will be included.