0

I have this code :

constructor(props) {
    super(props);
    this.dispatch = props.dispatch;
    this.state = {
        checked: [],
        expanded: [],
    };
    const {dispatch, match, t} = this.props;
    this.onCheck = this.onCheck.bind(this);
    this.onExpand = this.onExpand.bind(this);
}
onCheck(checked) {
    this.setState({ checked });
    console.log(this.state.checked);
    this.loadProducts(this.state.checked);
}
onExpand(expanded) {
    this.setState({ expanded });
}
render() {
    const { checked, expanded } = this.state;
    console.log(checked);
    ........
    <CheckboxTree
        nodes={this.props.chosenCategory.children}
        checked={checked}
        expanded={expanded}
        onCheck={this.onCheck}
        onExpand={this.onExpand}
        .......
    />

The problem is that in console.log from render function I have the correct checked value. But in the function onCheck checked have the previous value. I don't understand what's the problem. Can you help me please ?

GPiter
  • 779
  • 1
  • 11
  • 24
  • 1
    Does this answer your question? [Console.log() after setState() doesn't return the updated state](https://stackoverflow.com/questions/54713510/console-log-after-setstate-doesnt-return-the-updated-state) (`console.log()` directly after `setState()` will always show the value during the *current* render. The new state value won't be available until the next render. This is the expected behavior) – pilchard Jan 23 '21 at 14:47

2 Answers2

0

There are 2 types of setState, the first one takes an object as a parameter, and the second one takes a function as a parameter. The difference between the two is the first one is asynchronous and the second is synchronous.

So you need to use setState with function as a parameter.

onCheck(checked) {
    this.setState((state) => ({ checked}));
    console.log(this.state.checked);
    this.loadProducts(this.state.checked);
}
Soufiane Boutahlil
  • 2,554
  • 1
  • 7
  • 13
0

Due to the asynchronous behaviour of setState, we can't guarantee that the following line will have the updated value, at that particular instance.

In your case, if you want to log the updated value inside onCheck, the you can use the callback provided by the setState function.

onCheck(checked) {
    this.setState({ checked }, () =>  {
        this.loadProducts(this.state.checked); //param - checked will also do
        console.log(this.state.checked);
    });
}

now the console.log will execute, after successful setState.

Arun Kumar
  • 355
  • 3
  • 10
  • this.loadProducts(this.state.checked) the function here will receive the wrong value due to asynchronous of setState with an object as a parameter, it will receive the previous value of this.state.checked. – Soufiane Boutahlil Jan 23 '21 at 16:18
  • yes that is true, thanks for letting me know, will update. – Arun Kumar Jan 23 '21 at 16:20