React Checkbox Component with State Management
This challenge asks you to build a reusable checkbox component in React using TypeScript. A well-designed checkbox component is fundamental for user input and form creation, and this exercise will reinforce your understanding of component state, props, and event handling in React.
Problem Description
You need to create a React component called Checkbox that renders a single checkbox input element. The component should accept the following props:
label: (string) The text label to display next to the checkbox.checked: (boolean) A boolean value indicating whether the checkbox is initially checked.onChange: (function) A callback function that will be called when the checkbox's state changes (checked or unchecked). This function should receive the newcheckedstate as an argument.id: (string, optional) An ID for the checkbox element. If not provided, a unique ID will be generated.
The component should:
- Render a
<label>element containing thelabeltext and a<input type="checkbox">element. - The checkbox input should have the
checkedattribute set to the value of thecheckedprop. - The checkbox input should trigger the
onChangecallback function when its state changes. - If an
idprop is provided, it should be used as theidattribute for both the<label>and<input>elements. Otherwise, generate a unique ID (e.g., usinguuidor a simple counter). - The
labelelement should be associated with the checkbox input using thehtmlForattribute.
Examples
Example 1:
Input:
<Checkbox label="Agree to Terms" checked={true} onChange={() => {}} />
Output:
<label for="unique-id">Agree to Terms<input type="checkbox" id="unique-id" checked="true" /></label>
Explanation: A checkbox labeled "Agree to Terms" is rendered, initially checked, and calls the onChange function when clicked. A unique ID is generated.
**Example 2:**
Input: <Checkbox label="Subscribe to Newsletter" checked={false} onChange={() => {}} id="newsletter-checkbox" /> Output: <label for="newsletter-checkbox">Subscribe to Newsletter<input type="checkbox" id="newsletter-checkbox" checked="false" /></label> Explanation: A checkbox labeled "Subscribe to Newsletter" is rendered, initially unchecked, and calls the onChange function when clicked. The provided ID "newsletter-checkbox" is used.
Example 3: (Edge Case - Empty Label)
Input:
<Checkbox label="" checked={true} onChange={() => {}} />
Output:
<label for="unique-id"></label><input type="checkbox" id="unique-id" checked="true" />
Explanation: Handles an empty label gracefully, rendering an empty label element.
Constraints
- The component must be written in TypeScript.
- The component must be functional.
- The
onChangecallback function must be called with the correct boolean value (true or false) representing the new checked state. - The generated ID (if no
idprop is provided) must be unique within the component's lifecycle. A simple counter is acceptable for this exercise. - The component should be reasonably performant. Avoid unnecessary re-renders.
Notes
- Consider using React's
useStatehook to manage the internal state of the checkbox if you want to create a controlled component (although the problem description focuses on handling theonChangecallback). - You can use any standard JavaScript/TypeScript libraries for generating unique IDs, but avoid external dependencies if possible for simplicity.
- Focus on creating a clean, readable, and reusable component.
- Ensure the
htmlForattribute on the label correctly references theidof the checkbox input.