-1

I just started learning how to work with React and I ran into a problem that I still can't seem to solve.

I'm trying to program a simple app for adding tasks like a simple to-do list.

But when I want to add a task and save the data via useState, the new data is not written to the page.

i have code in file AllTasks.js:

     const [myTasks, setMyTasks] = useState(data);

    const tasksHandler = (id) => {
        const filteredTasks = myTasks.filter((oneTask) =>{
           return oneTask.id !== id;
        })
        setMyTasks(filteredTasks);
    }

    const checkID = () => {
        for(let i = 0; i < myTasks.length; i++){
            if(i === myTasks.length -1){
                return myTasks[i].id + 1;
            }
        }
    }

    const addNewTask = (newTask) => {
        let task = {
            id: checkID(),
            name: newTask
        };
        const newTasks = myTasks;
        newTasks.push(task);
        setMyTasks(newTasks);
    }

    const deleteAllTasks = () => {
        setMyTasks([]);
    }

    return(
        <div className='tasks'>
            <Title />
            <AddTasks addTask={addNewTask}/>
            {
                myTasks.map((oneTask) => {
                    const {id, name} = oneTask;

                    return <div className='one-task' key={id}>
                        <p>{name}</p>
                        <button onClick={() => tasksHandler(id)}><img src={deleteImg} alt='todoApp'/></button>
                    </div>
                })
            }
            <button className='main-button' onClick={deleteAllTasks}>Delete all tasks</button>
        </div>
    )
}

export default AllTasks;

The code in the AddTask.js file that I use to send the new task to the AllTasks.js file

import './AddTask.css';
import addImg from "../img/plus.png";

const AddTask = (props) => {

    const add = () => {
        const input = document.getElementById('new-task');
        const newTask = input.value;
        if(input.value.length > 0){
            props.addTask(newTask);
        }
    }

    return(
        <div className='add-task'>
            <input type='text' id='new-task'></input>
            <button id='send-task' onClick={add}><img src={addImg} alt='todoApp'/></button>
        </div>
    )
}

export default AddTask;

I don't understand why when I click on add task and run the addNewTask() function, why doesn't the added task appear on the page? When I upload new data to myTasks via setMyTasks(newTaskt)?

Thank you all for your reply.

Thomas
  • 11,958
  • 1
  • 14
  • 23
  • 1
    Everyone hates reading docs but I suggest you read through the docs once. Particularly the beta reactjs docs. https://beta.reactjs.org/learn/updating-objects-in-state – Binit Dec 11 '22 at 17:13
  • @Binit There should be a bot that scans react questions and automatically closes them. I see at least 5 questions like that per hour – Konrad Dec 11 '22 at 17:16
  • Your `checkID` function may create the same IDs over time, which doesn't break anything in this code, but still you can do better. Here an imo. better code: `const newId = useMemo((current = 0) => () => \`id${++current}\`, []);` – Thomas Dec 11 '22 at 17:30

3 Answers3

1

Try change final line of addNewTask function from setMyTasks(newTasks); to setMyTasks([...newTasks]);

nguyentanfake
  • 21
  • 1
  • 2
  • This still mutates the old state, but then makes a copy of that mutated array so that `setMyTasks` recognizes it as "new" value. – Thomas Dec 11 '22 at 17:22
1

This is because you are adding new data inside existing array, react needs a brand new array to update it's state and keep track of state.

In addNewTask function instead of adding element to the existing array you should do

setState((previousStateOfArray) => {
return [...previousStateOfArray, newElement];
})

Or shorthand would be setState(prev => [...prev, newElement])

Labham Jain
  • 308
  • 3
  • 8
0

Should use immutable state setting:

setMyTasks([...newTasks]);
Art Bauer
  • 479
  • 2
  • 5
  • This still mutates the old state, but then makes a copy of that mutated array so that `setMyTasks` recognizes it as "new" value. – Thomas Dec 11 '22 at 17:22