30

Fairly new to React with a potential silly question.

How is it possible that I can omit Reacts return statement with parenthesis.

const Nav = () => (
  <nav className="c_navbar">
    { some jsx magic here }
  </nav>
)

while I see other instances like this:

const Nav = () => {
  return (
    <nav className="c_navbar">
      { some jsx magic here }
    </nav>
  )
}

As far as I understand the () help when I return an object literal so that it doesn't mix it up with a code block. But I don't see this applicable here?

Thanks

supersize
  • 13,764
  • 18
  • 74
  • 133
  • 1
    It's not strictly a React thing. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – Herohtar Sep 28 '18 at 20:17
  • 1
    Read https://jaketrent.com/post/javascript-arrow-function-return-rules/ – Arup Rakshit Sep 28 '18 at 20:27
  • 2
    The question isn't a full duplicate of https://stackoverflow.com/questions/39629962/arrow-function-without-curly-braces . Neither linked question nor its answers address `return (...)` part which is important here. – Estus Flask Sep 28 '18 at 20:28
  • You can just as easily return a jsx component without the parenthesis if there are no line breaks. – mhatch Sep 28 '18 at 20:55

4 Answers4

28

The first snippet is implicit return. Parentheses are provided only for developer's convenience; it's possible to unambiguously parse the code without them, at the expense of readability:

const Nav = () =>
  <nav className="c_navbar">
    { some jsx magic here }
  </nav>

While the second snippet contains explicit return. This is the case when parentheses are commonly used in React, because when there's no optional expression right after return statement, there is no returned value.

  return
    <nav className="c_navbar">
      { some jsx magic here }
    </nav>

is parsed as

  return;
  <nav className="c_navbar">
    { some jsx magic here }
  </nav>

In order to be parsed correctly without parentheses, it should be:

  return <nav className="c_navbar">
    { some jsx magic here }
  </nav>

So parentheses are commonly used for consistency in both implicit and explicit returns and allow to improve the readability with proper indentation.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    great answer. When I need `{ }` because I will do some stuff before the return I definitely can't omit the return and it must be explicit, but I can still omit the `()` for that return. Correct? – supersize Sep 28 '18 at 20:42
  • 2
    Yes, you can omit `()` but only as long as returned value goes on the same line, `return – Estus Flask Sep 28 '18 at 21:10
9

This is a JavaScript question not a React Question.

1) Parenthesis () are used in an arrow function to return an object.

() => ({ name: 'Amanda' })  // Shorthand to return an object

That is equivalent to

() => { // Block body
   return { name : 'Amanda' }
}
  1. Parenthesis are also used to group multiline of codes on JavaScript return statement so to prevent semicolon inserted automatically in the wrong place.

class StarsComponent {
  constructor(size) {
    this.size = size;
  }
  
  render() {
    return (<div> 
            *
            </div>) // <--JavaScript engine inserts semicolon here
  }
}

Why? When you place your opening bracket on the same line as return: return ( You are telling JavaScript engine that it can’t automatically insert a semicolon until the bracket is closed.

For a single line statement, we don’t need to wrap it inside brackets.

class StarsComponent {
  constructor(size) {
    this.size = size;
  }
  
  // Not required to wrap brackets around a single line of code
  render() {
    return <div>*</div>;
  }
}

More information can be found here: https://medium.com/@leannezhang/curly-braces-versus-parenthesis-in-reactjs-4d3ffd33128f

leannez
  • 225
  • 3
  • 6
  • 1
    You should also note that implicit return works on more than just objects. It can return any single value, like a React component. The parenthesis in the OP's question are only needed because of the line breaks in jsx. – mhatch Sep 28 '18 at 20:54
5

It's not particularly a react syntax but a JavaScript one. There are two types of body types for arrow function declaration

  1. concise body - value is implicitly returned.
  2. block body - an explicit return is required.

Refer to the MDN documentation for more info.

dance2die
  • 35,807
  • 39
  • 131
  • 194
1

In JavaScript the ( params ) => x syntax is equivalent[1] to function( params ) { return x; }, so the return is there, it's just implicit.

If you have a function body wrapped in braces (e.g. a multi-statement body) inside an => function then there isn't an implicit return anymore.

e.g.

var someFunc1 = function( x, y, z ) {
    return x + y + z;
};

var someFunc2 = ( x, y, z ) => x + y + z;

var someFunc3 = ( x, y, z ) => {
    var result = x + y + z
    return result ;
}

[1] - Functions using => are like function()-functions, but they also have implicit this binding that cannot be re-bound which makes them suitable for event-handlers in web-page scripts, for example.

Dai
  • 141,631
  • 28
  • 261
  • 374
  • 1
    Your comment about "multi-statement body" is not technically true. It has nothing to do with multi-statement, it has to do with whether the function body is contained in an explicitly-defined block (with `{ }`) or whether an expression is given for the function body. – mhodges Sep 28 '18 at 20:20
  • 1
    Example `var fn = (x, y) => (x=x*y, x*2)`, `fn(4, 5)` will return `40` implicitly, even though it is executing 2 completely separate statements using the [comma operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator). – mhodges Sep 28 '18 at 20:24
  • @mhodges I've removed the C# comment to avoid confusing readers (in C# the `=>` syntax is used for Lambda Expressions and Expression-Bodied Methods and Properties, not "LINQ statements"). By "multi statement" I am referring to brace-wrapped bodies which can indeed contain only a single statement, but the majority of the time they contain multiple statements. I don't know the specific terminology for JavaScript's brace-wrapped function bodies. – Dai Sep 28 '18 at 20:24
  • @mhodges so I can still omit the return if I write multiple statements on the same line? – supersize Sep 28 '18 at 20:24
  • @supersize Technically yes, see my comment I just made a few seconds ago. IMO it's ill-advised, though. It's very poor readability – mhodges Sep 28 '18 at 20:25
  • @supersize I think you're using the term "statement" incorrectly. Also, JavaScript doesn't really have a concept of "lines". – Dai Sep 28 '18 at 20:25
  • 1
    @mhodges just saw it. I wouldn't write it, but this post is about understanding. Much appreciated! – supersize Sep 28 '18 at 20:26
  • @mhodges its a function body, not really a block statement. – Jonas Wilms Sep 28 '18 at 20:27
  • @JonasWilms The braces denote a [block of code](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block) (when not denoting an object definition). Said block of code gets executed as the function body, just as an expression would if you put an expression on the right hand side of an arrow function definition. – mhodges Sep 28 '18 at 20:31