Hone logo
Hone
Problems

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 new checked state 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 the label text and a <input type="checkbox"> element.
  • The checkbox input should have the checked attribute set to the value of the checked prop.
  • The checkbox input should trigger the onChange callback function when its state changes.
  • If an id prop is provided, it should be used as the id attribute for both the <label> and <input> elements. Otherwise, generate a unique ID (e.g., using uuid or a simple counter).
  • The label element should be associated with the checkbox input using the htmlFor attribute.

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 onChange callback function must be called with the correct boolean value (true or false) representing the new checked state.
  • The generated ID (if no id prop 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 useState hook to manage the internal state of the checkbox if you want to create a controlled component (although the problem description focuses on handling the onChange callback).
  • 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 htmlFor attribute on the label correctly references the id of the checkbox input.
Loading editor...
typescript