React/ReactJS: Update an Array Element in Redux Reducer State
In our previous tutorial on
using Redux with React/ReactJS, we have appended a couple of objects into the Redux state variable
books as its elements, which is of type
array.
Now what if we have to change/update that state variable at a specific
index? How do we replace an array element at index
i?
The official React/ReactJS documentation suggests the use of
immutability helper
update()
to handle such data.
We make use of the package react-addons-update. Install it.
npm i react-addons-update
Import the installed
react-addons-update package into your
reducer.js. We introduce a new action type
called UPDATE_ARRAY to update a state
variable of type array (which is
books here) at the particular index
i. Here is how it is done. The index of
the element to be changed is set at
[action.id].
// reducer.js
import update from "react-addons-update";
const INITIAL_STATE = {
books: []
}
export default (state = INITIAL_STATE, action={}) => {
switch(action.type) {
case "UPDATE_ARRAY":
return update(state, {
books: {
[action.id]: {
$set: action.content
}
}
});
default:
return state;
}
};
Inside action.js, we create one more
action creator called updateArray() just
to update that specific array element. Note carefully that this
updateArray() function has one extra field
id, which is the index of the array
element which is to be replaced. We create one wrapper function called
updateData() around
dispatch() which will be used in the React
component to send out an action to the store.
// action.js
const updateArray = (content) => {
return {
type: "UPDATE_ARRAY",
id: content.id,
content: content.element
}
}
const updateData = (obj) => {
return (dispatch) => {
dispatch(updateArray(obj));
}
}
export {
updateData
}
Now we get to the main component. In our
previous tutorial, inside
componentDidMount(), the first element
that was pushed to the books state
variable of type array in Redux store was
{
book_id: 1,
title: 'Dune',
author: 'Frank Herbert',
year: 1965
}
Here, we will replace it with a set of different values. We first pass
the updateData() function from
action.js as props to the component via
mapDispatchToProps. This is an element at index 0. This is
how you would do it.
this.props.updateData({
id: 0,
element: {
book_id: 1,
title: 'Nineteen Eighty-Four',
author: 'George Orwell',
year: 1949
}
});
Now the old data which was at index 0 got
replaced by this new data
{
book_id: 1,
title: 'Nineteen Eighty-Four',
author: 'George Orwell',
year: 1949
}