Race conditions with setState in React

Race conditions when calling setState can cause weird bugs.

Don't do stuff like this:

class MyComponent extends React.Component {
    componentDidMount () {
        doAjaxCall().then(data => {
            this.setState({origData: data})
            this.filterData();
        });
    }

    filterData () {
        let filteredData = doSomeFiltering(this.state.origData);
        this.setState({filteredData});
    }

    render () {
        // render original and/or filtered data
    }
}

Instead do:

class MyComponent extends React.Component {
    componentDidMount () {
        doAjaxCall().then(data => {
            this.setState(origState => {
                let newState = Object.assign(origState, {origData: data});
                return this.filterData(newState);
            });
        });
    }

    filterData (origState) {
        let filteredData = doSomeFiltering(origState.origData);
        return Object.assign(origState, {filteredData});
    }

    render () {
        // render original and/or filtered data
    }
}

React's setState can accept callable as an argument. That callable will receive current state object, and should return new modified state. By using setState this way, you dramatically reduce number of race conditions you have to deal with.

Another question is: why the hell is data filtered by component in the first place? Store should be handling that.

Read about Flux and Reflux.

Links

About me