Different ways of adding an element to the array result in different outputs
Unanswered
Philippine Crocodile posted this in #help-forum
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
@Philippine Crocodile ts
setTasks(currentTasks => {
const tasksId = currentTasks.map(task => task.id);
currentTasks.splice(tasksId.indexOf(task.id), 1);
const tasks = sortTasks([...currentTasks, data.data]);
return tasks
})
ts
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?
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-immutablesetTasks(currentTasks => {
return sortTasks([
...(currentTasks.filter(t => t.id !== task.id)),
data.data,
]);
});if you want to use mutable methods or otherwise don't want to be restricted by the state immutability rule, you can use immer: https://github.com/immerjs/use-immer
@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
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.
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
Not working:
Working:
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!