If the o
object contains a key/value pair of: foo: 'bar'
can I depend on these outcomes?:
// 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?
Anti-pattern: Unconditionally copying props to state Because of this, it has always been unsafe to unconditionally override state using either of these lifecycles. Doing so will cause state updates to be lost. At first, this component might look okay.
However, since JSX is used to express XML-like nodes that get turned into HTML, attribute/props are defined by adding the attributes/props to JSX expressions as name-value attributes. In the code example below I am defining a React <li> element node, using JSX, with five attributes/props.
Not only can JSX elements be passed as props to components, but we can also pass other components as props. In fact, there is a special type of prop that is automatically provided on the props object called children .
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
.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With