Learning Redux
上QQ阅读APP看书,第一时间看更新

Handling EDIT_POST – editing posts

Next, we will handle the EDIT_POST action type:

We start by parsing the action object:

case EDIT_POST: {
const { type, id, ...newPost } = action

This time, we will pull out the type and id properties, because we will need the id later, and it should not be part of the post object.

We use the Array.prototype.map() function to return a new state array. If you do not know this function, it has the following signature:

const newArr = arr.map(
(elem, index) => { ... }
)

As you can see, map() accepts a callback function. The map function executes the callback function on each element and creates a new array from the return values of that callback function. Basically, map lets us apply a function to all elements in an array.

For example, if we wanted to increase all numbers in an array by one, we could use the map function, as follows:

const numbers = [1, 2, 3]
const newNumbers = numbers.map(
number => number + 1
)
console.log(newNumbers) // outputs: [2, 3, 4]

We can use map to edit a single post in the array, by going through all posts and returning the original post object, except for the one element that matches the index:

  return state.map((oldPost, index) =>

First, we will make sure that the id value equals the index of the array because we want to edit only one of the posts:

    action.id === index

Now, we can overwrite the oldPost properties with the newPost properties using the spread operator as follows:

      ? { ...oldPost, ...newPost }
: oldPost
)
}

When the index value matches the id specified in the action, the post object will be overwritten with all other properties from the action. When the index value doesn't match, we simply return the oldPost.

Imagine that we have the following posts:

posts: [ 
{ user: 'dan', category: 'hello', text: 'Hello World!' },
{ user: 'des', category: 'welcome', text: 'Welcome to the blog' }
]

We want to edit the first post, so we dispatch the following action:

{ type: 'EDIT_POST', id: 0, text: 'Hi World!' }

Our reducer would match the post with the 0 index in the array, which is the first one. Then, we have the following values:

const oldPost = { user: 'dan', category: 'hello', text: 'Hello World!' }
const newPost = { text: 'Hi World!' }

We use the spread operator to combine the objects:

{ ...oldPost, ...newPost }

This means that it will first spread out all properties from the oldPost object:

{ user: 'dan', category: 'hello', text: 'Hello World!', ...newPost }

Now, all properties from the newPost object will get spread out, overwriting some of the oldPost properties, and resulting in a new object:

{ user: 'dan', category: 'hello', text: 'Hi World!' }