[英]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" }
重写的所述foo
从o
。
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.