简体   繁体   English

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

[英]Is the ordering of props in JSX important?

If the o object contains a key/value pair of: foo: 'bar' can I depend on these outcomes?: 如果o对象包含一个键/值对: foo: 'bar'我可以依赖于这些结果吗?:

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

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

In other words, is the ordering of properties while using the spread operator significant? 换句话说,使用扩展运算符时属性的排序是否显着?

yes, it is. 是的。 It works exactly as your example says 它的工作方式与您的示例完全相同

You example is translated into: 你的例子被翻译成:

// 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...*/}
/>

And therefore, it overrides always the last one 因此,它总是覆盖最后一个

Yes, ordering does matter. 是的,订购确实很重要。 The exact reason is how Babel transpiles the JSX. 确切的原因是Babel如何转变JSX。 You can see this in the Babel REPL : 你可以在Babel REPL中看到这个:

<MyComponent foo="should not override" {...o}>

</MyComponent>

Becomes: 变为:

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

Where _extends is just Object.assign , or if the browser doesn't support it, _extends is functionally the same. 其中_extends只是Object.assign ,或者如果浏览器不支持它, _extends在功能上是相同的。 Per the MDN documentation: 根据MDN文档:

Properties in the target object will be overwritten by properties in the sources if they have the same key. 如果目标对象中的属性具有相同的键,则它们将被源中的属性覆盖。 Later sources' properties will similarly overwrite earlier ones. 后来的资源属性同样会覆盖之前的属性。

(Emphasis is mine). (重点是我的)。 Thus, when Object.assign is used to pass props to the component, the target is { foo: "overridden" } and the source is o . 因此,当Object.assign用于将props传递给组件时,目标是{ foo: "overridden" } ,源是o Since foo exists in both the target and the source, foo in the target is overridden. 由于foo存在于目标和源中,因此目标中的foo被覆盖。 This also applies to: 这也适用于:

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

</MyComponent>

Here, the JSX is transpiled to the opposite: 在这里,JSX被反映出来:

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

It's a bit different because here, the target is an empty object, but the latter half of the quote from MDN applies. 它有点不同,因为在这里,目标是一个空对象,但MDN引用的后半部分适用。 The sources here are o and { foo: "overridden" } . 这里的来源是o{ foo: "overridden" } Since foo exists in both sources, the foo in source { foo: "overridden" } overwrite's the foo from o . 由于foo在两个源存在, foo在源{ foo: "overridden" }重写的所述fooo

Check out this sandboxed proof: 看看这个沙盒证明:

https://codesandbox.io/s/Q1GMx9KM9 https://codesandbox.io/s/Q1GMx9KM9

As you can see it behaves exactly as you theorized in your question. 正如您所看到的,它的行为与您在问题中理论化的完全相同。

EDIT SO Snippet: 编辑 SO片段:

 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')); 
 <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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM