Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does return { ...state, } in this reducer exactly mean?

This is reducer_posts.js from very simple blog react-redux app.

import _ from 'lodash';
import { FETCH_POSTS, FETCH_ONE_POST, DELETE_POST } from '../actions/index';

export default function (state = {}, action) {

  switch (action.type) {

    case DELETE_POST:
      return _.omit(state, action.payload);

    case FETCH_ONE_POST:
      return { ...state, [action.payload.data._id]: action.payload.data };

    case FETCH_POSTS:
      return _.mapKeys(action.payload.data, '_id');

    default:
      return state;
  }
}

_.omit(state, action.payload) is returning state without action.payload, so it is returning state without deleted post.

_.mapKeys(action.payload.data, '_id') creates an object with the same values as initial object, but new object has new key taken from action.payload.data._id

But I can't just get what in that code, this piece of syntax exactly does:

return {  ...state, [action.payload.data._id]: action.payload.data };

What does this line of code do? What does ... mean?

like image 443
John Taylor Avatar asked May 29 '17 15:05

John Taylor


2 Answers

What does this line of code do?

Basically it does two things:

  1. Adds old state properties to the new object by copying all enumerable properties from the state to the {}. Here is the quote form here:

An alternative approach is to use the object spread syntax proposed for the next versions of JavaScript which lets you use the spread (...) operator to copy enumerable properties from one object to another in a more succinct way. The object spread operator is conceptually similar to the ES6 array spread operator.

  1. Creates a new computed property with the key that is the result of evaluating action.payload.data._id and sets its value to the result of evaluating action.payload.data. Here is the quote from here:

Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets [], that will be computed as the property name. This is symmetrical to the bracket notation of the property accessor syntax, which you might have used to read and set properties already.

Here is the example in pure JS:

const action = {payload: {data: {_id: 'some'}}};
const oldState = {a: '3'};
const newState = {...oldState, [action.payload.data._id]: action.payload.data}
console.log(newState); // {a: '3', some: {_id: 'some'}}
like image 65
Max Koretskyi Avatar answered Oct 14 '22 13:10

Max Koretskyi


This line creates a brand new object based on all the available properties of current state and only updates the "action.payload.data._id" parameter.

as an example: When Redux is used as the application state management paradigm, to notify Redux about any changes in states, a new state object (reducer output) should be created to ensure the Redux that there is an actual state change occurred, (therefor the component will be re-rendered)

like image 30
Mohammad Ebrahimi Avatar answered Oct 14 '22 11:10

Mohammad Ebrahimi