es6 传播运算符如何处理对象到道具的转换?

How does es6 spread operator work on an object to props transformation?

我知道要让 {...todo} 在 Todo 组件中工作,必须将其转换为道具,例如:completed=false text="clean room" 但是展开运算符是如何做到这一点的呢?现在的{...todo}不就变成了{completed:false}, {text:"clean room"}吗?

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

es6 扩展运算符确实通过转换 {...todo} to {completed:false}{text:"clean room"}.

来工作

但是,JSX中使用了相同的运算符,但不一定相同。

来自 msdn docs

The spread syntax allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) or multiple variables (for destructuring assignment) are expected.

遵循这个想法,创建了 JSX spread operator。根据 React docs,

The ... operator (or spread operator) is already supported for arrays in ES6. There is also an ECMAScript proposal for Object Rest and Spread Properties. We're taking advantage of these supported and developing standards in order to provide a cleaner syntax in JSX.

既然这已经沿用了传播算子的思想,那么将两者统一起来确实是社区欢迎的想法

如前所述,此处扩展语法的使用与 ES6 无关,它是一个 JSX 结构。

JSX 只是 React.createElement 调用的语法糖。道具实际上作为对象传递给该函数。

大家可以使用Babel repl看看JSX是如何改造的

没有传播道具:

// In
<Component foo="bar" baz="42" />

// Out
React.createElement(
  Component,
  { foo: "bar", baz: "42" }
);

有传播道具:

// In
<Component foo="bar" {...xyz} baz="42" />

// Out
React.createElement(
  Component,
  Object.assign({ foo: "bar" }, xyz, { baz: "42" })
);

所以你可以看到,如果 props 包含一个 spread prop,它们被分成多个对象并简单地合并。