Next.js Discord

Discord Forum

Different ways of adding an element to the array result in different outputs

Unanswered
Philippine Crocodile posted this in #help-forum
Open in Discord
Philippine CrocodileOP
setTasks(currentTasks => {
            const tasksId = currentTasks.map(task => task.id);
            currentTasks.splice(tasksId.indexOf(task.id), 1);
            const tasks = sortTasks([...currentTasks, data.data]);
            return tasks
})


setTasks(currentTasks => {
    const tasksId = currentTasks.map(task => task.id);
    currentTasks.splice(tasksId.indexOf(task.id), 1);
    currentTasks.push(data.data);
    const tasks = sortTasks([...currentTasks]);
    return tasks
})


Yea, I know I shouldn't modify the state directly, but thats besides the point right now.

These two snippets of code should provide the same output because both of them just add something to the end of the array. But they result in different outputs. Why?

4 Replies

@joulev you are using mutable methods (`.splice`, `.push`) on a state. that never ends well, react states are meant to be immutable. <https://react.dev/reference/rules/components-and-hooks-must-be-pure#props-and-state-are-immutable> tsx setTasks(currentTasks => { return sortTasks([ ...(currentTasks.filter(t => t.id !== task.id)), data.data, ]); });
Philippine CrocodileOP
I knew you weren't supposed to do that with the tasks variable useState returns in [tasks, setTasks] = useState([]) but I thought I could do it in setState(() => {}).

For people in the future, if they stumble across this forum thread and wanna mutate the array anyway
I did some more testing and if you want to modify the current state, you have to create a new variable which you mutate instead. const newCurrentTasks = [...currentTasks]. Notice the .... That forces JavaScript to create a new, entirely new array, instead of using a reference to the currentTasks array.

What doesn't make sense to me is why the second snippet below produces the desired output but the first snippet doesn't. I added a console.log and both arrays passed to the sortTasks function are the same lenght and have the exact same data.

Not working:
setTasks(currentTasks => {
            const tasksId = currentTasks.map(task => task.id);
            currentTasks.splice(tasksId.indexOf(task.id), 1);
            const tasks = sortTasks([...currentTasks, data.data]);
            return tasks
})


Working:
setTasks(currentTasks => {
    const tasksId = currentTasks.map(task => task.id);
    currentTasks.splice(tasksId.indexOf(task.id), 1);
    currentTasks.push(data.data);
    const tasks = sortTasks([...currentTasks]);
    return tasks
})
Philippine CrocodileOP
1️⃣ bump!