8

Learn React 18: Using Uncontrolled Inputs

 10 months ago
source link: https://code.tutsplus.com/react-fundamentals-using-uncontrolled-inputs--cms-42012t
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
maxresdefault.jpg

Adding an Uncontrolled Input

When using a controlled input, we were responsible for setting and updating the values of our form input elements. This meant that we had to create onChange listeners for all these events to update values. We also used the value attribute to set the value for each input element.

With uncontrolled inputs, we don't have to worry about setting or updating input values so there is no need to create onChange event listeners or use a value attribute. Here is the code for our render() method with these things in mind.

render() {
2
    return (
3
      <div class="container">
4
        <h1>Random Number Generator</h1>

5
        <div className="range-container">
6
        <p>Lower Limit: {this.state.lowerLimit}</p>

7
        <p>Upper Limit: {this.state.lowerLimit + this.state.numberRange}</p>

8
        </div>

9
        <h2>{this.state.randomNumber}</h2>

        <form>
          <input type="number" ref={this.lowInput} />

          <input type="number" ref={this.rangeInput} />

          <button type="submit" onClick={this.handleSubmission}>Submit</button>

        </form>

      </div>

    );
}

We have added two input elements and a button to our form here. The input elements will dictate the values of lower limit and output range for our random number. The button has an onClick event listener that will handle the form submission and update the random number parameters.

Even though we are no longer in-charge of setting and updating input values, we still need to access them to update the parameters of our random number generator. We get this access with Refs. Refs are used to store reference to different elements inside the component. We can create a Ref by using React.createRef(). Here is the code for our constructor method where we create these Refs.

constructor(props) {
2
    super(props);
3
4
    this.rangeInput = React.createRef();
5
    this.lowInput = React.createRef();
6
7
    this.state = {
8
      numberRange: props.numRange,
9
      lowerLimit: props.low,
      randomNumber: Math.floor(Math.random() * props.numRange) + props.low
    };
    this.handleSubmission = this.handleSubmission.bind(this);
}

As I said earlier, we create Refs for our input elements inside the constructor. The state property now also includes a lowerLimit value to store the value of our lowInput input element. We also bind the handleSubmission() method to our class inside the constructor.

The handleSumbission() method will take the values from our input and sanitize them. After that, the values are stored in the component's state. We also bring the focus back to our lowInput element for a better user experience.

handleSubmission(e) {
2
    e.preventDefault();
3
4
    let newRange = parseInt(this.rangeInput.current.value);
5
    let newLow = parseInt(this.lowInput.current.value);
6
7
8
    if(isNaN(newRange) || newRange < 0) {
9
      newRange = 0;
    }
    if(isNaN(newLow) || newLow < 0) {
      newLow = 0;
    }
    this.setState({numberRange: newRange, lowerLimit: newLow});
    this.lowInput.current.focus();
}

As you can see, we use the current attribute of our refs in order to get access to different elements.

Now it is time to update our componentDidMount() method so that it uses the newly set limits for creating the random numbers.

componentDidMount() {
2
    this.numTimer = setInterval(() => {
3
      let tempVal = Math.floor(Math.random() * this.state.numberRange) + this.state.lowerLimit;
4
      this.setState({ randomNumber: tempVal });
5
    }, 2000);
6
}

The following CodePen demo shows our RandomGenerator component using uncontrolled inputs in action.

We have seen how controlled and uncontrolled inputs are different from each other from a developer's standpoint. These inputs also behave differently from a user's perspective.

Lets say you enter a non-numeric value in the input fields above. You will see that the input field actually displays the value. However, the lower limit value in the component's state will adjust to zero without changing the value of the input field. This is because we are not controlling the input here. On the other hand, try entering a non-numeric value in the input field of the previous tutorial and you will see that not only does it update the component state but also the input value. This is because we were in control of the input there.

Another thing that you will notice here is that we were able to take the focus back to our first input element while handling the form submission. It was possible because we have a reference to the input element and could call focus() to bring it into focus. We were not able to do that in the previous tutorial because we did not have a reference to the element.

For practice, you should try to modify the above component so that it uses controlled inputs. keep in mind that you will have to add onChange event listeners for both inputs to do so.

Final Thoughts

I am hoping that this tutorial helped you understand the difference between controlled and uncontrolled inputs. Controlled inputs require you to write more code to handle any changes in input values. However, they are considered the correct approach because they allow you to have a single source of truth in your components.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK