React - Use State to Toggle an Element (When to add extra parenthesis to a setState() function?)

Tell us what’s happening:

Hello everyone. My question here is why do I need to include parenthesis around the function code in the second solution example, but not the first? I am a little confused about that. I included them in my code which was similar to solution1, but it didn’t work.

solution1:

  // change code below this line
  toggleVisibility() {
    this.setState(state => { // no extra parenthesis here
      if (state.visibility === true) {
         return { visibility: false };
       } else {
         return { visibility: true };
      }
    });
  }
  // change code above this line

Solution2:

  toggleVisibility() {
    this.setState(state => ({ // the parenthesis is here encapsulating the semicolons
      visibility: !state.visibility
    }));
  }

I see in the instructions it says:

Note that you have to wrap the object literal in parentheses, otherwise JavaScript thinks it’s a block of code.

So why in the second solution, but not the first? Because it is a direct state change to the object and not JS if/else code? Thanks in advance.

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0

Challenge: React - Use State to Toggle an Element

Link to the challenge:

I think it is because you don’t have the return and you entered a block of code by using the curly braces. You could try to remove both the parentheses and curly braces because if you are using an arrow function and doing it on one line the return is implied and you can do it like:

this.setState((state) => console.log(state))

Note: Not addressing anything else about the code itself. Just the use of () and {}

Equivalent for your “no parentheses required” example, unambiguous, should be self-explanatory. Literally the same as this without the function keyword:

function (state) {
  if (state.visibility === true) {
    return { visibility: false };
  } else {
    return { visibility: true };
  }
};

Bearing in mind that you can elide the return keyword in an arrow function (it is applied automatically):

Equivalent for your “parentheses used” example when parentheses are used

function (state) {
  return {
    visibility: !state.visibility
  }
}

Equivalent for your “parentheses used” example when parentheses are not used

function (state) {
  return visibility: !state.visibility
}

If you return a single expression from an arrow statement, you can elide the return keyword.

Given that { and } are used for both object literals and to denote a function block, if you’re returning an object, JavaScript has to have a way to be able to tell that you meant “I’m returning an object”, not “what’s inside the curly brackets is the contents of the function, execute it”

1 Like

Thanks for both of your replies. I’m still wrapping my head around this. I decided to read through React’s own tutorial/manual because I was getting a little lost separating JavaScript, JSX, and React code. Anyways, I stumbled upon this tidbit in React’s documentation:

We split JSX over multiple lines for readability. While it isn’t required, when doing this, we also recommend wrapping it in parentheses to avoid the pitfalls of automatic semicolon insertion.

that quote is from here: https://reactjs.org/docs/introducing-jsx.html

On that note, the omitting of semicolons in React/JSX where Javascript would normally have them is throwing me off a bit too, so I’m hoping further study will help me sort this.

The JSX gets converted to JavaScript, but it’s written like HTML, so if you wanted React to render some HTML like this:

<div>
  <h1>Title</h1>
  <p>Some text here</p>
</div>

Then you could do the following to really make sure there were no possible issues when you used whatever tool you were using to take JSX and convert it to JavaScript

function Example() {
  return <div><h1>Title</h1><p>Some text here</p></div>;
}

Or you could hope that the tool will convert the JSX perfectly and also make it readable like this:

function Example() {
  return <div>
    <h1>Title</h1>
    <p>Some text here</p>
  </div>;
}

But then, for example, what happens if you accidentally do this?

function Example() {
  return 
    <div>
      <h1>Title</h1>
      <p>Some text here</p>
    </div>;
}

Or you could make sure the tool converted the JSX without any issues and make it readable at the same time:

function Example() {
  return (
    <div>
      <h1>Title</h1>
      <p>Some text here</p>
    </div>
  );
}

Just to put in my $.02.

If I do

() => {
  return 'howdy'
}

it is the same as this:

() => 'howdy'

Without curly braces, JS knows to return whatever follows.

There is a problem with objects though…

() => {
  foo: 'bar'
}

Is that open curly brace the start of a code block or an object literal? JS doesn’t know - it will assume that it is a code block. That is why you have to wrap the object literal in parentheses, to let it know that it is not a code block. This really only comes up with objects - because curly braces can mean two different things.

You can read more here.

2 Likes

Thanks everyone for your various replies

() => {
  foo: 'bar'
}

Fun fact, in that code foo: is interpreted as a labeled statement. As also explained in the MDN link.

1 Like