3

I am reading about Reactjs, and one thing that I don't understand in the following syntax (taken from here)

this.setState(state => ({showWarning: !state.showWarning}))

is the () around the object. I understand that we use () for JSX, but the object {showWarning: !state.showWarning} is a JS object. Also I found this notation when using Redux as in

const mapStateToProps = state => ({...})

Why do we do that in React?

BlackMath
  • 932
  • 7
  • 24
  • 2
    Does this answer your question? [ECMAScript 6 arrow function that returns an object](https://stackoverflow.com/questions/28770415/ecmascript-6-arrow-function-that-returns-an-object) – CRice Jun 24 '20 at 23:09
  • To make an object literal – Tanner Dolby Jun 24 '20 at 23:18

4 Answers4

4

It's not specific to react. Arrow functions have a shorthand which allows you to skip the explicit return if you only have one statement. So a function like this:

const example = (val) => {
  return 'foo'
}

can be shortened to this:

const example = (val) => 'foo';

But note that the way you do this is by leaving out the curly brackets of the function body. If you try to return an object, you're going to be sticking in curly brackets, so javascript thinks "ah, this is the function body", when really you want the brackets to mean an object literal. To clear up the ambiguity, you need to wrap the object in parentheses, so there's no possible way it could be interpreted as a function body.

const example2 = (val) => {
  return { foo: 'bar' }
}

// can't become this:
//const example2 = (val) => {
//  foo: 'bar' // this is not a key/value pair of an object! This is a labeled statement
//}

// so instead it becomes this:
const example2 = (val) => ({
  foo: 'bar',
});
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
3

It's not exclusive to React.

When using Arrow functions, the expression to the right of the arrow is returned. But in the case of objects, the interpreter would interpret the braces as a multi-line function.

The parenthesis are there to denote that an object is to be returned as opposed to a function block declaration.

Quoted from the Syntax section of MDN:

(param1, param2, …, paramN) => { statements }  
(param1, param2, …, paramN) => expression
// equivalent to: => { return expression; }

// Parentheses are optional when there's only one parameter name:
(singleParam) => { statements }
singleParam => { statements }

// The parameter list for a function with no parameters should be written with a pair of parentheses.
() => { statements }

// Parenthesize the body of a function to return an object literal expression:
params => ({foo: bar})
Sunny Patel
  • 7,830
  • 2
  • 31
  • 46
1

{showWarning: !state.showWarning} is definitely a valid javascript object but not everywhere it will work as an object because {} is also used for code block. If you return any object implicitly from an arrow function without () javascript will consider it a code block rather than an object

() is just used to make engine think that we are try to use an expression here not a code block which is statement

Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
1

This is ES6 syntax for running a function that returns an object.

Because Javascript functions can create a new block by wrapping curly braces around, there is some ambiguity as to whether you are about to create this new block or if you're trying to return an object using implict return. So by wrapping the object in () you tell JS that you are trying to return the object inside implictly.

It just keeps the code lean and is more modern so that's why people use it.

Examples:

const ex1 = () => 1 // returns 1, no ambiguity

const ex2 = () => {return 1} // same as above, but with explicit return

const ex3 = () => {a: 1} // error! thinks it's a new block, not an object

const ex4 = () => ({a: 1}) // returns {a: 1} because wrapped in ()
itsanewabstract
  • 1,006
  • 3
  • 12