Understanding controlled components

In React, we can use what is called controlled components to implement a form. A controlled component has its value synchronized with the state in React. This will make more sense when we've implemented our first controlled component.

Let's open our project in Visual Studio Code and change the search box in our app header into a controlled component by carrying out the following steps:

  1. Open Header.tsx and add the following imports:
import { ChangeEvent, FC, useState } from 'react';
import {
Link,
RouteComponentProps,
withRouter,
} from 'react-router-dom';
  1. Let's set the props type to RouteComponentProps and destructure the history and location props in the Header component: 
export const Header: FC<RouteComponentProps> = ({
history,
location,
}) => {
const handleSearchInputChange = (
e: ChangeEvent<HTMLInputElement>,
) => { ... }
  1. We need to wrap the component with the withRouter function to get these props passed into it. So, let's do this at the bottom of the file as we export this with the name HeaderWithRouter:
export const HeaderWithRouter = withRouter(Header);
  1. In App.tsx, we now need to import this wrapped Header component:
import { HeaderWithRouter as Header } from './Header';
  1. Back in Header.tsx, the default value for the search box is going to be the criteria route query parameter. So, let's get this from the destructured location object:
export const Header: FC<RouteComponentProps> = ({ history, location }) => {
const searchParams = new URLSearchParams(location.search);
const criteria = searchParams.get('criteria') || '';

const handleSearchInputChange = ...
}
  1. Let's create some state to store the search value in, defaulting it to the criteria variable we have just set: 
const searchParams = new URLSearchParams(location.search);
const criteria = searchParams.get('criteria') || '';

const [search, setSearch] = useState(criteria);
  1. Now, let's drive the search box value from this search state:
<input
type="text"
placeholder="Search..."
value={search}
onChange={handleSearchChange}
css={ ... }
/>
  1. Start the app by running the npm start command in Visual Studio Code's Terminal.
  2. Try to type something in the search box in the app header.

Nothing seems to happen; something is preventing us from entering the value.

We have just set the value to some React state, so React is now controlling the value of the search box. This is why we no longer appear to be able to type into it.

We are part-way through creating our first controlled input. However, controlled inputs aren't much use if users can't enter anything into them. So, how can we make our input editable again? The answer is that we need to listen to changes to the input value and update the state accordingly. React will then render the new value from the state.

  1. We are already listening to changes with the handleSearchInputChange function. So, all we need to do is update the state in this function, replacing the previous console.log statement:
const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
setSearch(e.currentTarget.value);
};

If we now go to the running app and enter something into the search box, this time, it behaves as expected.

  1. We are going to wrap input in form so that we can eventually invoke the search when the user presses the Enter key:
<form>
<input
type="text"
placeholder="Search..."
onChange={handleSearchInputChange}
value={search}
css={ ... }
/>
</form>

We are going to leave the implementation there for now. We'll implement the form submission later in this chapter in the Submitting forms section.

React-controlled components make sense once we understand what is going on. If we were to implement a form with several controlled components, we would have to create the state and a change event listener to update the state for each field. That's quite a lot of boilerplate code to write. Can we not create an abstraction to reduce the amount of repetitive code? Yes! We'll do just this in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.83.185