DEV Community

Cover image for Controlled & Uncontrolled Component
Jorjis Hasan
Jorjis Hasan

Posted on

Controlled & Uncontrolled Component

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;

Enter fullscreen mode Exit fullscreen mode

Uncontrolled component DevView


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 value null
  • Whenever any accordion gets clicked, the onClick function is invoked, and activeIndex is set to the current index.

  • By then, re-render happens. And this props isActive={activeIndex === index} validate and send True 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;

Enter fullscreen mode Exit fullscreen mode

Controlled component DevView


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.

Top comments (6)

Collapse
 
vilan profile image
coco

I have a question as to whether controlled or uncontrolled components are better

Collapse
 
jorjishasan profile image
Jorjis Hasan

Suppose you are building an e-commerce app. Initially, it has 1M product-card components in your app. Each product card has a toggle feature that allows some specific things on the card to be toggled or collapsed on click. To achieve that in an uncontrolled component, we need to have at least one state on each card. It turns out that our app is going to have MILLION states! Would it be performant?

Absolutely no. So, in the Controlled Component, there is just one state instead of a million. That state will stay in the parent. Whenever any of the Million products get clicked, we'll just share that state with that specific product card.

@vilan , can I make sense?

Collapse
 
vilan profile image
coco

Thank you very much for your answer. That's right. But in some nested dynamic form component encapsulation, the parent component manages all form state. In this scenario, is the design complexity of a controlled form component much more difficult than that of an uncontrolled form component?

Thread Thread
 
jorjishasan profile image
Jorjis Hasan

In my opinion, it won't matter much.

The design complexity of a controlled form component can indeed be more challenging than that of an uncontrolled form component, especially in the context of nested dynamic form components where the parent component manages all form states.

Thread Thread
 
vilan profile image
coco

thanks。Attention to you, stay in touch!

Thread Thread
 
jorjishasan profile image
Jorjis Hasan • Edited

@vilan Sure Buddy πŸ₯‚
Followed you. Share your linkedIn