Problem Statement
Build a tree of checkboxes where a parent and its children stay in sync. The tree can be nested to any depth.
Functional Requirements
- Render the tree: Show the items from
checkBoxesData(Fruits and Vegetables with their children), with each level indented. - Cascade down: Checking or unchecking a parent sets all of its descendants to the same value.
- Cascade up: A parent becomes checked when all of its children are checked, and unchecked when any child is unchecked.
- Show state: A debug panel prints the
checkedobject as JSON.
Technical Constraints
- Use one recursive
CheckBoxescomponent for every level. - Keep all checked values in a single
{ [id]: boolean }state object owned byApp.
Function Explanations
CheckBoxes Component
This is a recursive React component that renders a nested checkbox tree structure.
Props:
data: Array containing the hierarchical checkbox datachecked: Object holding the current state of all checkboxes (ID → boolean)setChecked: State setter function to update the checkbox states
handleChange Function
Purpose: Handles checkbox toggle events and updates the state with proper parent-child relationships.
Parameters:
isChecked: Boolean representing the new checked stateitem: The checkbox item object being toggled
JavaScript Methods Used:
- Spread operator (
...prev): Creates a shallow copy of the previous state - Computed property name (
[item.id]): Dynamically assigns a property using the item's ID - Optional chaining (
?.): Safely accesses nested properties that might be undefined
updateChildren Function (Inner Function)
Purpose: Recursively updates all child checkboxes to match the parent's state.
Parameters:
parentItem: The parent checkbox item whose children need updating
Process:
- Checks if children exist using optional chaining
- Iterates through each child using
.forEach() - Sets each child's checked state to match the parent
- Recursively calls itself for any grandchildren
verifyChecked Function (Inner Function)
Purpose: Validates and updates parent checkbox states based on their children.
Parameters:
item: The checkbox item to verify
Returns: Boolean indicating if the item (and all its children) are checked
Process:
- Base case: For items without children, returns the item's own checked state
- For items with children, uses
.every()to check if all children are checked - Recursively processes the entire subtree
- Updates the parent's state based on its children's states
State Differences
prevState vs newState:
prevState(referenced asprevin the code): The current checkbox state before the changenewState: The updated checkbox state after processing the change and its cascading effects
Key Differences:
newStatecontains the direct change to the clicked checkboxnewStateincludes cascading updates to all children (throughupdateChildren)newStateincludes cascading updates to all parents (throughverifyChecked)
Complete Code Flow
-
App Component Initialization:
- Creates an empty
checkedstate object usinguseState({}) - Renders the
CheckBoxescomponent with the initial state
- Creates an empty
-
User Interaction:
- User clicks a checkbox, triggering the
onChangeevent handleChangereceives the new checked state and the item object
- User clicks a checkbox, triggering the
-
State Update Process:
setCheckedis called with a function that receives the previous state- A new state object is created with the clicked checkbox's state updated
updateChildrenis called to propagate the state to all descendantsverifyCheckedis called on all top-level items to update parent states based on children- The final
newStateis returned, becoming the newcheckedstate
-
Rendering:
- React re-renders the component with the updated state
- Each checkbox is rendered with its correct checked status
- Children checkboxes are rendered recursively
- Debug panel displays the current state in JSON format
-
Key Behaviors:
- Checking a parent checks all its children (cascade down)
- If all children are checked, the parent automatically checks (cascade up)
- If any child is unchecked, the parent becomes unchecked (cascade up)