1

When I do the following, everything works fine:

this.state.sections.map(({ a, b }) => <MenuItem { ...{a,b} }/>)

However, when I do the following(which I think would be the equivalent, I get an error saying ... is expected:

this.state.sections.map(({ a, b }) => <MenuItem { a, b }/>)

Why so? Isn't ...{a,b} the equivalent of a, b in JS?

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
Claudiu Bbn
  • 113
  • 4
  • "*Isn't `...{a,b}` the equivalent of `a, b` in JS?*" No, it's not. One creates a new object, the other is using the [comma operator](https://stackoverflow.com/questions/3561043/what-does-a-comma-do-in-javascript-expressions) which would ignore `a` and just gives you `b`. However, that's for *JavaScript*, the React syntax here might be a different thing - I'm not well versed in it. – VLAZ Apr 27 '20 at 10:24
  • @VLAZ so the equivalent of `...{a,b}` is `{a,b}`, right? – Claudiu Bbn Apr 27 '20 at 10:27
  • the brackets in the case of { a, b } are used to denote a javascript expression as a prop in JSX (executing `a, b` as a prop, which is invalid because the prop has no name), whereas the ...{a,b} is simulating a spread operator onto props, where the key names are used as prop names. – user120242 Apr 27 '20 at 10:30

1 Answers1

2

They are not equivalent in JSX context:

// For given function component
const MenuItem = ({ a, b }) => <></>

// Use cases
(props /* {a,b} */) => <MenuItem {...props} />
<MenuItem a={a} b={b} />
<MenuItem { ...{a,b} }/>

// Transpiles to
React.createElement(MenuItem, { a, b });
// Syntax Error
// as this JSX doesn't transpile to React.createElement 
<MenuItem {a, b} />

/*
Unexpected token, expected "..." (1:11)
> 1 | <MenuItem {a, b} />;
*/

But in JS they do result the same structure:

a = 5;
b= 7;
{ a, b } // { a: 5, b: 7 }
{ ...{ a, b } // { a: 5, b: 7 }

Be aware of the difference between code transpiled by babel compiler and JS.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118