What is the controlled props pattern in React?

Overview

There are times when we'll have a component whose internal state we want to override. We'll also want to compel the parent component to open it. Let's first take a look at controlled and uncontrolled components.

Controlled components

A controlled component uses props to get its current value, and callbacks are used to notify changes. By processing the callback, managing its state, and delivering the updated values as props to the controlled component, a parent component “controls” it.

Let's say we have an accordion, and we do not want to control the state internally. Instead, we want the parent component to handle the state and the values passed down as props and an onChange to handle the toggling of the accordion.

The App component

We have our parent component called App, and we have the Accordion component as a child in the App parent component. We also have an open state and a handleToggle function, which we pass down as props to the Accordian component to be able to display the accordion and also toggle the open state.

import { useState } from "react";
import Accordion from "./accordion";
import "./App.css";
function App() {
const [open, setOpen] = useState(false);
function handleToggle() {
setOpen(!open);
}
return (
<div className="App">
<Accordion open={open} handleToggle={handleToggle} />
</div>
);
}
export default App;

The Accordion component

We parse the open and handleToggle function to the Accordion component, where the value of the states in the parent component controls the display of the accordion and the toggling of the display component.

import React from "react";
const Accordion = ({ open, handleToggle }) => {
return (
<div style={{ border: "1px solid black" }}>
{open && <h1>Accordion 1</h1>}
<button onClick={handleToggle}>Toggle</button>
</div>
);
};
export default Accordion;

Summary

The Control Props pattern from the code above allows the parent component to control state values within the child component completely.

Uncontrolled components

An uncontrolled component is the opposite of a controlled component, and allows a component to handle its own state values and functions. Most of the state manipulation is done in the component itself.

Let's use the Accordion component again to demonstrate this.

import React from "react";
const Accordion = () => {
const [open, setOpen] = useState(false);
function handleToggle() {
setOpen(!open);
}
return (
<div style={{ border: "1px solid black" }}>
{open && <h1>Accordion 1</h1>}
<button onClick={handleToggle}>Toggle</button>
</div>
);
};
export default Accordion;

The parent component no longer controls the child component. The child component handles its state and functionality internally.

The mixed control component

We can use the mixed control component in an uncontrolled or controlled manner. It receives the prop’s initial value and sets it in the state. It then reacts to changes in props through useEffect to bring the state up to date with the props.

Free Resources