Hi, I don't understand why it wants an anonymous function inside state

Tell us what’s happening:

Your code so far


class MyComponent extends React.Component {
constructor(props) {
  super(props);
  this.state = {
    visibility: false
  };
  // change code below this line
this.toggleVisibility = this.toggleVisibility.bind(this)
  // change code above this line
}
// change code below this line
toggleVisibility () {
  if (this.state.visibility){
    this.setState ({ 
      visibility: false });
  } else {
      this.setState ({ 
        visibility: true})
    }
}
// change code above this line
render() {
  if (this.state.visibility) {
    return (
      <div>
        <button onClick={this.toggleVisibility}>Click Me</button>
        <h1>Now you see me!</h1>
      </div>
    );
  } else {
    return (
      <div>
        <button onClick={this.toggleVisibility}>Click Me</button>
      </div>
    );
  }
}
};

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36.

Challenge: Use State to Toggle an Element

Link to the challenge:

Hello there,

If you would like to read more about this, here is the official documentation on the asynchronous nature of setState: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Upon using the setState method, you are not guaranteed your state will be updated in any particular order. I learnt this this hard way, when doing the JavaScript Calculator Project. The issue with this is when any one state object is dependant upon another state object, or the current prop object value - as seen in the example:

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

Essentially, when this.setState is called, this.state.counter could be equal to 1, but, due to other processes in the application, by the time the state object counter is actually updated, this.state.counter is equal to something else.

If you use a function:

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

state and props are snapshots of the current state and props at the time of call, as opposed to time of execution/completion.

Hope this helps

1 Like

So, the arguments state and props passed to the function inside the setState are sent by a function caller(or something like that) as parameters and therefore they are the latest values?

It is very hard to understand without seeing what is happening at the background(if something is happening)

When you use this does it refer to the state on the UI? Can we not remove this and write the following code to update the current state or does it have to be done with a function? Confusing²

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

The best way to wrap your head around it is to play around with React.

Have a go at this quick demo: https://codepen.io/sky020/pen/wvMWYMV?editors=0010

It refers to the component itself. So, you create a state object in the constructor (this.state), and the this in both cases refers to the same thing - the component.

Hope it helps

1 Like

Thank you for the demo Sky. It is very helpful.

But I still don’t understand how a function(handleUpdate) updates the latest and the regular way(updateCounter) doesn’t. When I use your demo, in both cases the state is updated, so I can’t see any difference apart from the functional one updates by 3 at a time and the normal way by 1.

This is the whole point. They should both do the same - update by 3.

Without the updater function, multiple setState calls can be accidentally batched into one call.

okay, that makes sense but still hard to get my head around how using function does that. I understand that I should use function but I would understand it better if I knew how it works.

Thank you very much for your answers and the demo.

Have a good day.

Well, if you are comfortable with TypeScript, then you could have a look at the definition of setState:

setState<K extends keyof S>(
   state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),
   callback?: () => void
): void;

forceUpdate(callback?: () => void): void;
render(): ReactNode;

Or, maybe better to understand, the hook useState:

export function useState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {
  const dispatcher = resolveDispatcher();
  return dispatcher.useState(initialState);
}

Have fun.

It’s like a chain, right. Learn HTML, CSS and then JavaScript, then React and Redux and then React-Redux and now TypeScript. I can’t… :worried: I am overload with too many questions already.

I think I will live with "just use the bloody function when you update the state" statement.

Also, these parenthesis and curly braces are confusing too. On the demo you sent me, you use arrow functions and there is return. I thought with arrow functions we can omit return. When I try to remove, it doesn’t work straight away as I need to arrange the parenthesis and curly braces correctly. :pullingmyhairout:

Like you said, playing helps quite a lot.

Thank you.

1 Like