0

Why doesn't react update the style in the setState? The color of the text does not update to green with the setState function, it remains blue.

class Practice extends Component {

    state = {
        count: 0,
        color: "blue"
    }

    style = {
        color: this.state.color
    }



    handleIncrement = () => {
        this.setState({ count: this.state.count});
        this.setState({ color: "green"});
    }

    render() {
        return(
            <div>
                <h1 style={this.style}>
                    The color in this state is {this.state.color}. 
                    The number in count is {this.state.count}.
                    <button
                    onClick={this.handleIncrement}
                    >
                    Increment 
                    </button>
                </h1>
            </div>
        );
    }

    }

3 Answers 3

3

Information on how a component should render should flow from state alone - this will allow you to call setState to change how the component renders. Putting a .style property on the component instance itself won't work - put it into the state instead.

Rather than duplicating the color in different parts of the state, put it in just one place, in the style object in state.

Not 100% certain, but you also probably want

this.setState({ count: this.state.count});

to be

this.setState({ count: this.state.count + 1 });

class Practice extends React.Component {
    state = {
        count: 0,
        style: {
          color: 'blue',
        }
    }

    handleIncrement = () => {
        this.setState({ count: this.state.count + 1 });
        this.setState({ style: {
          ...this.state.style,
          color: "green"
        }});
    }

    render() {
        return(
            <div>
                <h1 style={this.state.style}>
                    The color in this state is {this.state.style.color}. 
                    The number in count is {this.state.count}.
                    <button
                    onClick={this.handleIncrement}
                    >
                    Increment 
                    </button>
                </h1>
            </div>
        );
    }
}

ReactDOM.render(<Practice />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

Sign up to request clarification or add additional context in comments.

Comments

2

While other answers explain well why your code is not working in terms of React state, there is one thing I noticed that might be another point of confusion.

When you're assigning a value to your style property like this:

style = {
    color: this.state.color
}

you might be thinking that you're assigning style.color a "reference" to the string that this.state.color points to. What actually happens is that you're assigning the value "blue", because the string is a primitive type in JS. So after you've done that, your style object is really just

{
    color: "blue"
}

So even if you somehow change the value of this.state.color, this fundamentally wouldn't result in updating the value of this.style.color.

2 Comments

Yes, that's where my confusion was coming from. What I don't understand though is if setState calls the render function, the entire block of code that gets rerendered and returned. Wouldn't this.style re-call this.state.color and then it would be green?
@Devin your style assignment happens in the field initializer (which is analogous to putting it into the constructor), so outside of render(). In your render() you're only looking at current value of the style property
1

state in react app will only update using setState if and only if you have inclued the state in this.state if you are using constructor or state property without constructor.

Live Demo

Codesandbox Demo

You should create state as:

state = {
    count: 0,
    style: {
      color: "blue"
    }
  };

and update the state as:

handleIncrement = () => {
    this.setState((oldState) => {
      return {
        count: oldState.count + 1,
        style: {
          ...oldState.style,
          color: "green"
        }
      };
    });
  };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.