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

65 views Asked by At

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 answers

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.