cat-t
cat-t

Reputation: 1376

Caching the value of a method in react component

I'm coming from an Ember background which had computed properties that were lazily computed and then cached until the dependent properties change.

Say I have the following setup in react:

export default React.createClass({
    getInitialState: function(){
        return {
            firstName: 'John',
            lastName: 'Smith'
        }
    },

    fullName: function(){
        console.log('full name is computed')
        return `${this.state.firstName} ${this.state.lastName}`;
    },

    changeFirstName: function(){
        this.setState({ firstName: 'somethingElse'});
    },

    changeUnrelatedState: function(){
        this.setState({ blah: 'zzzzzz' });
    },

    render: function(){
        return (
            <div>{this.state.firstName} and {this.state.lastName} makes {this.fullName()}</div>

            <button onClick={this.changeFirstName}>Change first name</button
            <button onClick={this.changeUnrelatedState}>Change some state variable</button
        );
    }
});

When I click the 'Change some state variable' button, the component re-renders and the fullName method recomputes. This is a simple example, but what if the fullName method performed an expensive computation? This would run every single time the state changes, regardless of whether or not firstName or lastName changed but still triggering that expensive operation.

Is there a react way of caching the value of a method, and not re-computing it during each render?

Upvotes: 0

Views: 2483

Answers (1)

Henrik Andersson
Henrik Andersson

Reputation: 47182

By extracting our expensive computation into a new component we can implement shouldComponentUpdate and only recalculate when needed. This way we get "caching" of already once computed values.

var FullNameComponent = React.createClass({
    shouldComponentUpdate: function (nextProps, nextState) {
        //Props was the same no need for re-rendering
        if (nextProps.firstName === this.props.firstName) return false;

        //Props has changed, recalculate!
        return true;
    },
    performExpensiveCalculation: function () {
        console.log('rerenders');
        return `${this.props.firstName} ${this.props.lastName}`;
    },
    render: function () {
        return (<div>{this.performExpensiveCalculation()}</div>);
    }
});

Upvotes: 1

Related Questions