React Inputs

Handling inputs in React is similar to how you'd handle them in HTML, except we can take advantage of React hooks to manage the state of the input inside our main React App component. This is known as a controlled component because the state is controlled by our code with React hooks.

We'll be using the standard HTML <input> tag, React hooks and styled-components for easy styling and stateful functionality.

Controlled vs Uncontrolled Input Examples

We're demonstrating both a text input controlled by React, and an uncontrolled component controlled by the native browser DOM. Native HTML forms will automatically store the value of the input inside the DOM. So, if you don't want to keep track of state with React, you can just handle the submit event with native browser functionality, and capture that inside a React callback. In this example, we handle this in submitForm. This is not really a typical approach in React apps because most of the time you will want the state variable inside your app, for example to perform real-time validation.

React Text Input props

Note that when discussing these input "props", we're referencing the standard HTML attributes, and so as with all React props, they are the same as the HTML attributes except for callback functions like onChange which are camelCase. Feel free to reference HTML documentation for other standard attributes that can be set through props.

React input value prop

The value prop is what determines the input's value. For text inputs, this is simply the current text value of the input, making it simple to understand when writing stateful logic. For checkboxes and radio buttons, it's the checked prop, as we describe in following lessons.

React input onChange prop

The onChange prop is a function that responds when the user interacts with the input. The browser tells us that a new value has been detected. However, we have not saved this value state anywhere in our application, so that's where we use hooks to create a "custom React hook", which is really just a function that returns the dynamic value/onChange props.

Using React hooks with inputs

So, the key is that we use the useState hook inside a helper method which we call useInput. This itself now becomes a "custom hook". Because all inputs share the same value and onChange props, this stateful functionality becomes reusable for any future inputs we want to create in our app.

We declare the onChange callback inside this hook, which uses the setValue callback given to us from React hooks. As a reminder, value and setValue are just names we created, as the useState hook doesn't require specific names for these attributes. We added an optional defaultValue argument we provide in case you would want to initialize the value (from data from a server for example) inside the useState call itself. So, now that we have our local input value and onChange props, we return those and then use the ...spread notation to place these props on our StyledInput.

Menu
Lesson 2/7
import React, { useState } from "react";
import styled from "styled-components";
// Styling a regular HTML input
const StyledInput = styled.input`
  display: block;
  margin: 20px 0px;
  font-size: 18px; 
  padding: 8px; 
  border: 1px solid lightblue;
`;
// Creating a custom hook
function useInput(defaultValue = "") {
  const [value, setValue] = useState(defaultValue);
  function onChange(e) {
    setValue(e.target.value);
  }
  return {
    value,
    onChange,
  };
}

export default function App() {
  // Using a fancy shared React hook to control input state
  const inputProps = useInput();

  // Using native DOM form submission to store state
  function submitForm(event) {
    // Prevent the default event because it causes a page refresh
    event.preventDefault();
    const data = new FormData(event.target);
    alert(data.get("myInput"));
  }

  return (
    <div>
      <h1> React Input Examples </h1>
      <h2> Controlled input </h2>
      <p>
        This input is <i> controlled </i> by React hooks{" "}
      </p>
      <StyledInput {...inputProps} placeholder="Type in here" />
      <span>Value: {inputProps.value} </span>
      <h2> Uncontrolled input </h2>
      <p>
        This input's state is <i> not </i> controlled by React, it relies on
        native DOM form submissions. Submitting will parse the form values.
      </p>
      <form onSubmit={submitForm}>
        <label>
          Name:
          <StyledInput placeholder="Type in here" name="myInput" type="text" />
        </label>
        <input type="submit" value="Submit" />
      </form>
    </div>
  );
}