Is the ordering of props in JSX important? Is the ordering of props in JSX important? reactjs reactjs

Is the ordering of props in JSX important?


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. You can see this in the 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. Per the MDN documentation:

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. Since foo exists in both the target and the source, foo in the target is overridden. This also applies to:

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

Here, the JSX is transpiled to the opposite:

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. The sources here are o and { foo: "overridden" }. Since foo exists in both sources, the foo in source { foo: "overridden" } overwrite's the foo from o.


Check out this sandboxed proof:

https://codesandbox.io/s/Q1GMx9KM9

As you can see it behaves exactly as you theorized in your question.

EDITSO Snippet:

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>