SiberianGuy
SiberianGuy

Reputation: 25312

Unexpected token when mapping in React

I'm rendering a select element and I need to pass keyValues to my component. To gather keyValues, I map real object's values this way:

 <Field keyValues={clients.map(client => {
     key: client.Name,
     value: client.Id 
})} />

But as result I get an error Unexpected token, expected ;. The error points to value. What am I missing?

Upvotes: 0

Views: 4000

Answers (1)

Andrew Li
Andrew Li

Reputation: 57964

This is because {} is treated as a block, so your code is just identifiers with colons and values in the middle of nowhere... this is obviously invalid outside of an object literal, thus the error.1

The reason why is because arrow functions follow a certain syntax. Per the ECMAScript 2015 Specification:

14.2 Arrow Function Definitions

Syntax

ArrowFunction :
  ArrowParameters [no LineTerminator here] => ConciseBody

ConciseBody :
  [lookahead ≠ { ] AssignmentExpression
  { FunctionBody }

As you can see, the arrow function allows for a concise body, which may be a block with a function body.

Because you are trying to return an object literal that happens to use curly braces, it is confused for a block and your property names and values are also confused for the function body.

To fix this, wrap the object literal in parentheses for an object to be returned:

<Field keyValues={clients.map(client => ({
    key: client.Name,
    value: client.Id 
}))} />

The reason why this works is because only expressions can be in parentheses. Per the specification again:

12.2 Primary Expression

Syntax

CoverParenthesizedExpressionAndArrowParameterList :
  ( Expression )
  ( )
  ( ... BindingIdentifier )
  ( Expression , ... BindingIdentifier )

Since a block is not an expression, it cannot be inside parentheses, so the {} is assumed to be an object, thus an object is returned (an object is an expression).


1 In your example, key is treated as a label. Since your line of code is an expression (client.Name), it must be terminated by a semicolon. Since there is a comma instead, the error is thrown reporting a semicolon was expected but got comma.

Upvotes: 4

Related Questions