Use State to Toggle an Element - please help me understand

Hello,

Can someone help me understand this challenge, please? (https://www.freecodecamp.org/learn/front-end-libraries/react/use-state-to-toggle-an-element )

I don’t understand, where does this.state.counter come from and what are we supposed to do actually? Where did we mention this.props.increment as well, and what is the point of this challenge? I have read this several times but still don’t get it. I opened the hint option, but even if I read that I don’t understand… What I do understand is that the visibility should toggle between true and false, and that I have to bind the this keyword to the method in the constructor. But I just don’t understand the examples posted here, like:

this.setState({
  counter: this.state.counter + this.props.increment
});

or


this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

Hi,
I might be a bit off in terminology, since I forgot some specs since I learnt React but the first example is a regular state update, where you simply assign a new value to a state field. The second example is called functional state update where you tell react to operate on an existing state. Read react docs for a more elaborate explanation. But a quick example is if you need to determine some value based on a previous one, you use the second example. Like you know that a number 2 follows number 1 and nothing else.
The thing about binding this variable in a constructor is a JS thing, it’s a procedure to preserve the context in which a method operates (bind a method to a specific object, in other words), has nothing to do with React specifically, but worth to know nevertheless.
Finally, you’re doing something wrong because there’s no counter in your linked challenge. You have to setState to either false or true, not count something.

1 Like

The setState method is asynchronous. React likes to batch these calls (in its own time), so you can not depend on the state/props to be updated “real-time” if you use the first syntax. However, if you use the second version (using the function), you are guaranteed to have the most recent state/props available to you as the argument to the function. If you always use the second version, you will never have to wonder if state has the most current data.

1 Like

You are referencing the example code which assumes there is a pre-existing state prop named counter and that a prop named increment was passed to the component.

1 Like

okay, so counter and increment are some imaginary props?

but where from did we get the counter and increment like some imaginary props? Why there is no original state I could refer to?

The original state gets set in the component’s constructor. The code on the left side isn’t a complete component, it’s just giving examples of how to call setState on some theoretical component.

The code in the challenge to the right is for a different component, and does does show the initial state being set, just before the // change code below this line" comment. It’s also the only place you should ever see this.state assigned to directly.

1 Like

alright, so they are not some built in things. Thanks!

Thanks a lot everyone, I think I finally figured this out!

I don’t understand how “using a function with setState guarantees you are working with the most current values of state and props.” Can I just remove this from the following to update the most current state without using a function?

this.setState({
  counter: this.state.counter + this.props.increment
});

I think I understand the concept of “React likes to batch these calls” like Randell said. I have to simplify it to understand, so I say: a batch of calls are being delivered(or accumulated to be delivered) so that there would be updates, including state update. That batch contains the latest version of state , whatever is on UI is not the latest. Is this something to do with React having a virtual DOM?

Is the crucial difference between 2 ways of updating state

  • removing this from the regular way of state update or
  • using a function or
  • both?

How does using a function to update the most current value of state work? How using a function can access the batched state value and not the regular way of updating state?

The problem is that anything that runs after your setState call not using the callback may still be using the old stale state, since it won’t actually update until the end of the current render cycle. Thus you need the callback if you’re using the state immediately afterward, since the callback does have the most up-to-date state.

The VDOM isn’t directly involved in this, but it is part of the reason for the architecture that made things this way.