Controlled Components

    Uncontrolled components store their state internally, while controlled components expect their state to be passed in from their parent.

    This typically applies to user input components. Most of the built-in form components (like input, select, etc) are typically used as controlled components, accepting a value and onChange prop. However, if value isn't supplied, these components act as uncontrolled components, with their state initialized internally.

    Uncontrolled components

    Suppose we want to create an TextInput component that supports submitting a text value via an onSubmit callback.

    In this example, we store the input element's state internally in our TextInput component. The component API is then just a single prop, onSubmit. However, we have no way to access the current state of the input element outside of this component.

    Controlled components

    In this example, we store the input element's state externally in the parent App component, passing it in via value and listening for changes via onChange. The component API now includes 3 props, so it's a little more complex, but we often prefer this approach so that we can potentially use the current state of the input element even before it's been submitted via onSubmit.