Categories
React Tips

React Tips — Input Focus and Choices Controls

Spread the love

React is the most used front end library for building modern, interactive front end web apps. It can also be used to build mobile apps.

In this article, we’ll look at how to focus inputs and binding values of checkboxes and radio buttons to states.

Set Focus On Input After Render

To focus an input, we have to use the native DOM element focus method to do it. The method is available to input elements so we can call it.

We can use the useEffect hook to run something when the component renders. If we pass in an empty array as the 2nd argument, then the callback we pass into useEffect only runs when the component first loads.

For instance, we can write the following to do that:

import React from "react";

export default function App() {
  const input = React.createRef();
  React.useEffect(() => input.current.focus(), []);
  return (
    <div className="App">
      <input ref={input} />
    </div>
  );
}

In the code above, we have the useEffect hook and the input ref created with the createRef method, which passed into the ref prop of the input.

Then in the useEffect callback, we call input.current.focus() to call the focus method of our input element.

In the end, when we load the page, we’ll see that the input is focused when App loads as we desired.

Checkbox

To create checkboxes, we have to set the checkbox value as the value of the checked prop. Then onChange handler will take the checked value and then set it to the state we passed in as the value of the checked prop.

For instance, we can write the following to do that:

import React from "react";

export default function App() {
  const [selected, setSelected] = React.useState({});
  const handleInputChange = e => {
    const { name, checked } = e.target;
    setSelected(selected => ({
      ...selected,
      [name]: checked
    }));
  };
  return (
    <div className="App">
      <form>
        <label>
          apple:
          <input
            name="apple"
            type="checkbox"
            checked={selected.apple || false}
            onChange={handleInputChange}
          />
        </label>
        <label>
          orange:
          <input
            name="orange"
            type="checkbox"
            checked={selected.orange || false}
            onChange={handleInputChange}
          />
        </label>
        <label>
          grape:
          <input
            name="grape"
            type="checkbox"
            checked={selected.grape || false}
            onChange={handleInputChange}
          />
        </label>
      </form>
      <p>
        {Object.keys(selected)
          .filter(k => selected[k])
          .join(", ")}
      </p>
    </div>
  );
}

Making checkboxes work properly is tricky. In our handleInputChange function, we have to make sure that name and value properties of e.target have to be accessed from a synchronous context, so it can’t be inside the callback that we pass into setSelected . If we don’t do that, we get a warning saying that ‘ This synthetic event is reused for performance reasons happening’

In the setSelected function, we spread the existing properties of selected , and then update the name and checked values from e.target into the returned object in the setSelected callback.

The name value is from the value of the name attribute of each checkbox.

To get rid of the ‘A component is changing an uncontrolled input of type text to be controlled error in ReactJS’ error, we have to set a default value for each checked prop. In the code above, we set them to false .

Radio Buttons

Radio buttons are similar to checkboxes, but only one radio button in a group can be checked at one time. For instance, we can write the following code to bind the radio button’s checked value to a state as follows:

import React from "react";

export default function App() {
  const [selected, setSelected] = React.useState("");
  const handleInputChange = e => {
    setSelected(e.target.value);
  };
  return (
    <div className="App">
      <form>
        <label>
          apple:
          <input
            name="fruit"
            type="radio"
            value="apple"
            checked={selected === "apple"}
            onChange={handleInputChange}
          />
        </label>
        <label>
          orange:
          <input
            name="fruit"
            type="radio"
            value="orange"
            checked={selected === "orange"}
            onChange={handleInputChange}
          />
        </label>
        <label>
          grape:
          <input
            name="fruit"
            type="radio"
            value="grape"
            checked={selected === "grape"}
            onChange={handleInputChange}
          />
        </label>
      </form>
      <p>{selected}</p>
    </div>
  );
}

In the code above, we have the checked prop which is set to the expression that checks if the selected value is set to given value in the value prop.

Then in the handleInputChange function, we can call setSelected by writing setSelected(e.target.value) since the radio button sets e.target.value is set to the value of the radio button.

Therefore, the selected value will be displayed when we click the radio button, and we also see the radio buttons change the selection as soon as we click the radio button.

The checked prop controls the rendering of which radio button is selected and the value displayed in the p tag is updated with the handleInputChange function.

Conclusion

Setting the values of checkboxes is tricky in React. We’ll get warnings in the console if we didn’t set a default value in the checked prop of the checkbox. We’ll also get warnings if we access e.target within the callback of our state change functions.

Radio buttons are easier to deal with in React since we just set the value as a string when we click a radio button.

Focusing inputs is easy since we can just attach a ref to an input and then call focus on it.

Leave a Reply

Your email address will not be published. Required fields are marked *