1

I am learning redux follow redux tutorial,when I saw todos todos-github example something confuse me:
Todo.js

const Todo = ({ onClick, completed, text}) => (
  <li
    onClick={onClick}
    style={{
      textDecoration: completed ? 'line-through' : 'none'
    }}
  >
    {text}
  </li>
)


TodoList.js

const TodoList = ({ todos, onTodoClick }) => (
  <ul>
    {
      todos.map(todo =>
      <Todo
        key={todo.id}
        {...todo} //how does it work?
        onClick={() => onTodoClick(todo.id)}
      />
    )}
  </ul>
)

todos is an array ,todo is an object:

enter image description here

Todo item's props:

enter image description here

As I know now,the Todo,TodoList component function pass on params by using ES6 Destructuring assignment , but how {...todo} work ? it must do something to props, the {} in this is stand for it's a javascript syntax ,so ...todo is a Varargs to Todo component function? I dont know, any help appreciate.

L.Ann
  • 88
  • 9

1 Answers1

3

We can check what {...todos} compiles to using Babel's REPL.

As you can see in the link above (I removed some stuff for clarity, but it should be simple enough) the part where the Todo component is created and {...todo} is passed as a prop gets compiled to:

React.createElement(Todo, _extends({ key: todo.id }, todo));

(The onClick prop has been omitted for simplicity - were it included, you would see _extends({ key: todo.id, onClick: /* onClick function */ }, todo)

So the {...todo} prop actually causes Babel to generate this _extends function, which is defined as:

var _extends = Object.assign || function (target) { 
  for (var i = 1; i < arguments.length; i++) { 
    var source = arguments[i]; 
    for (var key in source) { 
      if (Object.prototype.hasOwnProperty.call(source, key)) { 
        target[key] = source[key]; 
      } 
    } 
  } 
  return target; 
};

(The code above is generated as a one-liner by Babel - I cleaned it up for legibility)

So, as you can see, passing a prop using destructuring assignment into a React component causes all the properties of the destructured object to be copied into the props object passed to the component on creation. This behavior is not a standardized ES6 feature - instead, it is a part of JSX syntax.

In summary: If your todo object looks like:

{ completed: false, id: 0, text: "test1" }

Passing {...todo} as a prop is the equivalent of passing

completed={false} id={0} text="test1"

as props, and you can do this because it is a feature of the JSX specification.

Pedro Castilho
  • 10,174
  • 2
  • 28
  • 39