A React component is a reusable building block for an interface or application behavior. Its boundary is a design choice: a breakfast-ordering form can render radio inputs directly, but a RadioGroup component gives repeated option lists a shared interface. Start with the boundary the current application needs rather than anticipating requirements that have not appeared. section 2.2.1
Start with a small interface
RadioGroup accepts a name, an options array, and an onChange callback. It renders a labeled input for each option, tracks the selected value locally, and passes changes to the application. This is enough for the initial form, but an array becomes restrictive when individual options need their own JSX content or properties. section 2.2.1 section 2.2.3
When options grow more varied, the Composite pattern moves their structure into child components: a RadioGroup contains RadioGroup.Option elements, and each option owns details such as its value, label, or popular designation. This makes the UI easier to recombine, at the cost of a more elaborate component interface. It is useful when that flexibility matters, not merely because a hierarchy is possible. section 2.2.3 section 2.2.5
<RadioGroup name="bread" onChange= {onChange("bread")}> #1
<RadioGroup.Option value="bagel"> #2
Bagel #2
</RadioGroup.Option> #2
<RadioGroup.Option value="roll"> #2
Roll
</RadioGroup.Option>
<RadioGroup.Option value="croissant" isPopular> #3
Croissant
</RadioGroup.Option>
</RadioGroup>
The bread selector shows the change from an options array to child components, including an option-specific property. section 2.2.3
A component boundary also affects how the UI is built, checked, and delivered:
- Do not treat changed props alone as a re-render trigger. A child re-renders when its parent renders; changing a ref value without rendering the parent does not render the child. section 3.1.1
- Test interactive components through user actions and observable results. Vitest and React Testing Library support black-box checks, while the Arrange-Act-Assert pattern structures the test. section 10.2 section 10.4
- A route can itself be a component that displays server-loaded data. Next.js passes data through getServerSideProps; the shown Remix route retrieves loader data with useLoaderData. section 11.3.2
- For a shared UI library, define component behavior and interfaces from product requirements, then test them. Owning the library permits variants and fixes without waiting on a third party. section 13.0









