BrownRecluse
BrownRecluse

Reputation: 1670

Reactjs: updating state immediately

Complete Reactjs newbie here. I know setState() is asynchronous. I know if I do setState() then the states are queued and batched, so I will not see the state changed immediately. Fair enough.

I have also read the following link and other questions in SO:

https://reactjs.org/docs/react-component.html#setstate

I can use: callback methods in setState, componentDidUpdate() lifecycle method, concat if the state is an array etc. I get all these ways. My problem is a simple one, also I am banging my head on this issue for past 2 days so I am literally at my wit's end now.

I have this logic:

class ItemList extends React.Component {
    constructor(props) {
        super(props);
        this.state = {showCompleted: false};
        this.shouldShowFullList = false;
        this.onShowCompleted = this.onShowCompleted.bind(this);
    }

    onShowCompleted(event) {
        this.setState({showCompleted: event}, () => {this.shouldShowFullList = this.state.showCompleted;});
    }

    render() {
        if (this.shouldShowFullList) {
            return this.renderAllItemsIncludingCompleted();
        } else {
            return this.renderOnlyNotCompletedItems();
        }
    }

    ...

The logic is self-explanatory. My problem is even when I call this.shouldShowFullList in callback method of setState(), it still does not show an updated value. Value of this.shouldShowFullList is false when it should be true and vice versa. What is the best way to have the value of this.shouldShowFullList in lockstep with the this.state.showCompleted?

NOTE: onShowCompleted() is a callback method triggered from a child component. When a checkbox called "Show Completed" is checked, I should show a complete list of items, or else just the items which are not completed - something like ToDo list.

Upvotes: 1

Views: 1987

Answers (1)

Alexandre Nicolas
Alexandre Nicolas

Reputation: 1949

At onShowCompleted do

this.setState({ showCompleted: true })

or if you want toggle the value

this.setState({ showCompleted: !this.state.showCompleted })

Then in the render method you can do

 if (this.state.showCompleted) {
   return this.renderAllItemsIncludingCompleted();
 } else {
   return this.renderOnlyNotCompletedItems();
 }

When you set a state using setState the method render is called with this.state updated. I think the callback (second argument) of this.setState is called after the render.

Because updating this.state make a new render it seems that react is pushing you to use this.state in the render method. In fact it's made for this usage. If you want to make a variable that have no purpose in the render you can use this.myVariable. Best pratice is to use only this.stateand this.props in the render (or function that depend of it).

Upvotes: 1

Related Questions