JSX中道具的排序是否重要?

时间:2017-06-16 14:03:36

标签: javascript reactjs ecmascript-6 react-jsx spread-syntax

如果o对象包含一个键/值对:foo: 'bar'我可以依赖这些结果吗?:

// foo will be 'bar'
<MyComponent
    foo='should not override'
    {...o}
  />

// foo will be 'overridden'
<MyComponent
    {...o}
    foo='overridden'
  />

换句话说,使用spread运算符时属性的排序是否显着?

3 个答案:

答案 0 :(得分:5)

是的,确实如此。它的工作方式与您的示例完全相同

您的示例已翻译为:

// foo will be 'bar'
<MyComponent
    {/* ...other 'o' keys/values...*/}
    foo='should not override'
    {/* ...other 'o' keys/values...*/}
    foo='bar'
/>

// foo will be 'overridden'
<MyComponent
    foo='bar'
    {/* ...other 'o' keys/values...*/}
    foo='overridden'
    {/* ...other 'o' keys/values...*/}
/>

因此,它总是覆盖最后一个

答案 1 :(得分:2)

是的,订购确实很重要。确切的原因是Babel如何转变JSX。您可以在Babel REPL

中看到这一点
<MyComponent foo="should not override" {...o}>

</MyComponent>

变为:

React.createElement(MyComponent, _extends({ foo: "overridden" }, o));

_extends只是Object.assign,或者浏览器不支持,_extends在功能上是相同的。根据MDN文档:

  

如果目标对象中的属性具有相同的键,则它们将被源中的属性覆盖。后来的属性将同样覆盖之前的属性。

(重点是我的)。因此,当Object.assign用于将道具传递给组件时,目标为{ foo: "overridden" },源为o。由于目标和来源都存在foo,因此会覆盖目标中的foo。这也适用于:

<MyComponent {...o} foo="overridden">

</MyComponent>

在这里,JSX被反映出来了:

React.createElement(MyComponent, _extends({}, o, { foo: "overriden" }));

它有点不同,因为在这里,目标是一个空对象,但MDN引用的后半部分适用。这里的来源是o{ foo: "overridden" }。由于foo存在于两个来源中,因此来源foo中的{ foo: "overridden" }会覆盖来自foo的{​​{1}}。

答案 2 :(得分:1)

查看此沙盒证明:

https://codesandbox.io/s/Q1GMx9KM9

正如您所看到的,它的行为与您在问题中的理论完全一致。

修改 SO片段:

&#13;
&#13;
class MyComponent extends React.Component {
  render() {
    return <div>{this.props.foo}</div>
  }
}

const styles = {
  fontFamily: 'sans-serif',
  textAlign: 'center',
};

const o = { foo: 'bar' };

const App = () =>
  <div style={styles}>
    <h2>Spreading after explicit property</h2>
    <MyComponent foo="will be overriden" {...o} />
    <h2>Spreading before explicit property</h2>
    <MyComponent {...o} foo="was overriden" />
  </div>;

ReactDOM.render(<App />, document.getElementById('root'));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
&#13;
&#13;