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?






Updating an Item in an Array

– Alexander Staroselsky
Sep 13 '18 at 4:58





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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)