How do I properly update an item in my array in redux without mutating?
How do I properly update an item in my array in redux without mutating?
const state = [
list:
];
The list is a list of student objects, for example:
list: [
id: 1, name: "Mark", attendance: true ,
id: 2, name: "John", attendance: false
]
I have a button that triggers a post request to an API to change attendance to true. Post request returns the student object that was changed as in e.g.:
id: 2, name: "John", attendance: true
This works fine and if no errors, will dispatch ATTENDANCE_SUCCESS
.
ATTENDANCE_SUCCESS
Now, with this kind of set-up:
export function students(state, action) {
let latestState = state[state.length - 1],
newState = Object.assign(, latestState);
switch (action.type)
case "ATTENDANCE_SUCCESS":
if (action.res.errorCode == 0)
// Need to change redux state 'attendance' value to true for a student with ID returned from the POST request
Initially, I did:
const studentChanged = newState.list.find(function(student)
return (
student.id ===
action.res.data.id
);
);
studentChanged.attendance = true;
But it mutates the state in the redux store (although I am not sure how it's exactly happening since I assumed newState is already a copy).
What's the proper way?
1 Answer
1
The following would update a single item in the array. The critical aspect here is that if the id
of the item does not match the id
from the action payload, it returns the item unaltered, otherwise it updates the attendance
property. Array.prototype.map
returns a new array so it would be immutable.
id
id
attendance
Array.prototype.map
export function students(state, action)
switch (action.type)
case "ATTENDANCE_SUCCESS":
if (action.res.errorCode == 0)
return state.map(student =>
// we want to leave non matching items unaltered
if (student.id !== action.res.data.id)
return student;
return ...student, attendance: true ;
);
return state;
default:
return state;
Here is a StackBlitz to demonstrate the functionality.
Hopefully that helps!
What does ...student, attendance: true do? It's as if it's copying the entire student object but just changing attendance property to a different value?
– catandmouse
Sep 13 '18 at 5:52
Correct, It's the Object Spread Operator. It's effectively
Object.assign()
, just more succinct. Copy all enumerable properties, then additional argument values, in this case the property attendance
, get merged into that newly created object.– Alexander Staroselsky
Sep 13 '18 at 6:02
Object.assign()
attendance
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Updating an Item in an Array
– Alexander Staroselsky
Sep 13 '18 at 4:58