React

Changing State via User Input

PRO
Outline

Framing the problem

Lets start with the code from our last post:

var Water = React.createClass({
    getInitialState: function() {
        return {
            currentTemp: 10
        };
    },

    render: function() {
        // empty variable that will hold either "Liquid", "Solid", or "Gas"
        var stateOfMatter;

        // If temp is on/below freezing, it's a solid
        if (this.state.currentTemp <= 32) {
            stateOfMatter = 'Solid';

        // if temp is on/above boiling, it's a gas
        } else if (this.state.currentTemp >= 212) {
            stateOfMatter = 'Gas';

        // otherwise it's just a liquid
        } else {
            stateOfMatter = 'Liquid';
        }

        return (
            <div>
                <p>At { this.state.currentTemp }°F, water is considered to be a "{ stateOfMatter }" state of matter.</p>
            </div>
        );

    }
});

Every time we change currentTemp in getInitialState we have to refresh the page to see the updated result. That’s really lame, so lets create an input field where you can simply type in a temperature and have it update in real time. To do this, we’ll need to figure out two things:

  • How do you capture data from input fields in React components?
  • How do you update the state of a React component?

Capturing data from an input field

To help standardize cross browser (and platform) development, React provides a handful of helper components and methods for interacting with forms/inputs. For our use case, the React docs show how you can create a “controlled component” input that uses the “onChange” property to pass along the input’s value (amongst other things) to another method.

Lets implement this in our code. In render's return statement, lets add an input field whose value is tied to this.state.currentTemp and onChange calls a method called setTemperature:

return (
    <div>
        <input type="text" onChange={ this.setTemperature } value={ this.state.currentTemp } />
        <p>At { this.state.currentTemp }°F, water is considered to be a "{ stateOfMatter }" state of matter.</p>
    </div>
);

After getInitialState but before render, create a setTemperature method that takes the input’s event as its single argument:

setTemperature: function(e) {
    // e.target.value is the text from our input
},

Great! Now that we have the method working, the last thing we need to do is figure out how to update our state’s currentTemp with e.target.value.

Updating state with setState

Most people that are new to React will often make the mistake of trying to update state by modifying the state object directly (i.e. this.state.currentTemp = 100;). This is wrong and won’t work, as React doesn’t watch the state object for changes. Instead, React exposes us with a method called “setState” that we can pass updated state values to.

To set the temperature in our code above, simply call this.setState({currentTemp: e.target.value}); inside of setTemperature — and now everything should work! You can check out the working code here!