1

I'm trying to understand why es6 object spread behaviour is different between objects and when it's used in React components to spread props.

The following makes sense to me:

const a = {
  a:1,
  b:2
}

const c = {...a}

Now variable c will have the same properties as variable 'a' with key value pairs in this format of a:1, b:2.

This doesn't make sense:

<Mycomponent {...a} />

turns the props into "a={1} b={2}". Why does it behave in this way instead of the usual way which is key value pairs a:1, b:2?

I would like to understand why this works like this so I can better understand the language.

I've seen tutorials and articles which explain how spread works in both cases but I haven't found an answer why it spreads differently?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
j obe
  • 1,759
  • 4
  • 15
  • 23
  • Because these are two different operators working on different objects. Both are "spread" but they are not the same "spread". Consider the `+` operator on numbers and then consider what it does on strings. – Sulthan Nov 04 '20 at 18:50
  • Does this answer your question? [What do these three dots in React do?](https://stackoverflow.com/questions/31048953/what-do-these-three-dots-in-react-do) – Aib Syed Nov 04 '20 at 18:51
  • Thanks @Sulthan I think understanding that they are not the same type of spread is the key for me understanding this, I thought they are the same thing and should behave the same way. – j obe Nov 04 '20 at 18:58
  • @jobe Also note how spread works on arrays and function arguments. It's still *spreading* something, but everytime it does it differently. – Sulthan Nov 04 '20 at 19:18
  • @Sulthan in those cases it didn't confuse me as arrays are a different type of object but in this case the props object seems like a regular object as I described 'a' in my question, so I would expect them to spread in the same way as well. – j obe Nov 04 '20 at 22:53
  • Keep in mind that *syntax* itself is meaningless. It's the interpreter/pre-processor that associates meaning to syntax, and that meaning often depends on the *context* of a particular piece of syntax. The context of `{...a}` in `` is a JSX tag, so `{...a}` means something slightly different than in other context ("props spread" instead of object spread). *Conceptually* they are the same though (and in this specific case, if you know how JSX is converted to JavaScript, they are in fact identical). – Felix Kling Nov 05 '20 at 08:46
  • You could also flip this the other way round: `a={1}` in an JSX tag context has the same meaning as `a: 1` in an object literal context. Don't get hung up on how things "look" like, because as I said, meaning comes from the interpreter. That *behavior* is what's important. – Felix Kling Nov 05 '20 at 08:48
  • @FelixKling Thanks, I think I just understand well when I know the rules of the language so in this case when both props and in my example 'a' could be the same object, I would expect the object spread to do the same thing. I guess I have to understand that the context of the JSX element is what will change the meaning of how it works. I know that JSX is converted to a React.createElement call, how can that help me understand they are identical? – j obe Nov 05 '20 at 14:53
  • *"how can that help me understand they are identical?"* `` is converted to something like `React.createElement(Foo, Object.assign({bar: "42"}, a))`. And `{...a}` itself (object literal) is the same as `Object.assign({}, a)`. – Felix Kling Nov 05 '20 at 15:02
  • React.createElement(Foo, Object.assign({bar: "42"}, a)) should this not be React.createElement(Foo, Object.assign({bar: "42"}, ...a)) – j obe Nov 05 '20 at 18:20

1 Answers1

1

<Mycomponent {...a} />

turns the props into "a={1} b={2}". Why does it behave in this way instead of the usual way which is key value pairs a:1, b:2?

But it is doing key/value pairs of a:1 and b:2. The following code...

<Mycomponent a={1} b={2} />

... tells react to create a props object that looks like { a: 1, b: 2 }. And when you use the spread syntax, it also tells react to create a props object that looks like { a: 1, b: 2}.

Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • I don't understand the last part of what you wrote, both examples you're giving are telling React to create a props object? but when you use the spread syntax, how is that props object being spread turned into a={1} instead of a:1 – j obe Nov 04 '20 at 18:59
  • Props is always an object. The familiar way to create that object is to use JSX syntax and "a={1} b={2}".This may not look like an object, but it is. This code is telling react to create the object `{ a: 1, b: 2}`. `how is that props object being spread turned into a={1}` Since "a={1}" means "an object with a: 1", nothing needs to be done. It's already an object, and you're just making a copy of it. – Nicholas Tower Nov 04 '20 at 19:06
  • Try it out yourself: on [babeljs.io/repl](https://babeljs.io/repl), paste in ``, and see what it gets transpiled to. You'll see that it created an object `{ a: 1, b: 2 }` – Nicholas Tower Nov 04 '20 at 19:07
  • Thanks for clarifying, I think one of the other comments helped me understand by explaining it's a different type of spread operator and that made it clearer. – j obe Nov 04 '20 at 23:16