Is the order of the props important in JSX?

If the object o

contains a key / value pair:, foo: 'bar'

can I depend on these results ?:

// 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 when using the spread operator meaningful?

+3


source to share


3 answers


Yes it is. It works exactly the same as your example says

You, for example, translate to:



// 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 so it always always overrides

+3


source


Check out this isolated proof:

https://codesandbox.io/s/Q1GMx9KM9

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



EDIT SO 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>
      

Run code


+1


source


Yes, the order matters. The exact reason is in the way Babylon translates 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 it's _extends

simple Object.assign

, or if the browser doesn't support it, it's _extends

functionally the same, According to MDN documentation:

Properties on the target will be overwritten by properties on the sources if they have the same key. Properties of later sources similarly overwrite earlier ones.

(My emphasis). Thus, when Object.assign

used to pass props for a component, the target { foo: "overridden" }

and the source is o

. Since it foo

exists in both the target and the source, foo

the target is overridden. This also applies to:

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

</MyComponent>

      

Here the JSX is converted to the opposite:

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

      

This is slightly different because the target here is an empty object, but the second half of the quote from MDN applies. Sources here o

and { foo: "overridden" }

. Since it foo

exists in both sources, foo

the source { foo: "overridden" }

overwrites foo

from o

.

+1


source







All Articles