Controlled & Uncontrolled Component
Jorjis Hasan
Posted on June 3, 2024
Uncontrolled π½
In the example, each accordion has its own state(isOpen
). By default, it is set to false
. On click, it flips the value of the state variable(isOpen
) to true or false
. Based on the isOpen
value, it expands and collapses.
Since it controls its own state and doesn't rely on its parents, the children are uncontrolled components.
ππ½ App.js
const AccordionSection = ({ title, children }) => {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>{title}</button>
<span>{isOpen && children}</span>
</div>
);
};
const UncontrolledAccordion = () => {
return (
<div>
<AccordionSection title="Button 1">Content 1</AccordionSection>
<AccordionSection title="Button 2">Content 2</AccordionSection>
<AccordionSection title="Button 3">Content 3</AccordionSection>
</div>
);
};
export default UncontrolledAccordion;
Controlled β¬οΈ
Unlike an uncontrolled component, if the parent controls the child's state heavily or the child relies on his parent, that child is a Controlled component.
In the example below, we removed the accordion's ability to control itself and gave that power to the parent. Let's inspect the code.
- Render the accordions without functionality.
- Create state variable
activeIndex
with valuenull
Whenever any accordion gets clicked, the
onClick
function is invoked, andactiveIndex
is set to the currentindex
.By then, re-render happens. And this props
isActive={activeIndex === index}
validate and sendTrue
in props.The accordion that gets clicked will get a
True
boolean value and will be expanded.
Even in the preview of our code, we can see that the parent's state changes every time a child clicks. The parent is controlling the child via props.
ππ½ App.js
const AccordionSection = ({ title, children, isActive, onClick }) => {
return (
<div>
<button onClick={onClick}>{title}</button>
{isActive && <span>{children}</span>}
</div>
);
};
const ControlledAccordion = () => {
const [activeIndex, setActiveIndex] = useState(null);
return (
<>
{["Content 1", "Content 2", "Content 3"].map((content, index) => (
<AccordionSection
key={index}
title={`Button ${index + 1}`}
isActive={activeIndex === index}
onClick={() => setActiveIndex(activeIndex === index ? null : index)}
>
{content}
</AccordionSection>
))}
</>
);
};
export default ControlledAccordion;
NB: In case anyone is wondering how I got this developer view, it's actually a Chrome extension called React Developer Tools, available in the extension store.
Posted on June 3, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.