Hone logo
Hone
Problems

Mastering Component Communication: Implementing useImperativeHandle

Often, React components need to expose specific methods or values to their parent components for imperative control. While direct DOM manipulation is generally discouraged, there are scenarios where direct access to a child component's capabilities is necessary. This challenge focuses on implementing the useImperativeHandle hook to precisely control what methods and values a parent component can access from its child.

Problem Description

You are tasked with creating a custom Counter component that exposes a reset method and a currentValue property to its parent using useImperativeHandle. The Counter component should manage its own internal state for the count. The parent component should be able to increment the counter and, when a button is clicked, imperatively call the reset method on the Counter and display its currentValue.

Key Requirements:

  1. Counter Component:

    • Must maintain an internal count state, initialized to 0.
    • Should have a button to increment the count by 1.
    • Must use forwardRef to accept a ref from its parent.
    • Must use useImperativeHandle to expose a specific API to the parent.
      • The exposed API should include a reset function that sets the count back to 0.
      • The exposed API should include a currentValue property that returns the current count state.
  2. App (Parent) Component:

    • Must render the Counter component.
    • Must obtain a ref to the Counter component.
    • Must have a button to trigger the reset method on the Counter.
    • Must display the currentValue from the Counter component after resetting.
    • Should also display the current count directly rendered by the Counter component for comparison.

Expected Behavior:

  • When the App component mounts, the Counter displays "Count: 0".
  • Clicking the "Increment" button in the Counter component increases its displayed count.
  • Clicking the "Reset Counter" button in the App component:
    • Calls the reset method on the Counter component.
    • Updates the displayed "Reset Count:" in App to reflect the currentValue obtained after the reset.
    • The Counter component itself should visually update to show "Count: 0".

Edge Cases:

  • Ensure the ref is correctly forwarded and that useImperativeHandle is used within the Counter component's functional component.
  • The currentValue exposed should be the value after any operations (like reset) have been performed by the parent.

Examples

Example 1: Initial State and Incrementing

Input:
- App component renders Counter.
- Counter initializes count to 0.

Output:
[In the browser]
--------------------------
Counter Component:
  Count: 0
  [Increment] button

App Component:
  [Reset Counter] button
  Reset Count: 0
--------------------------

Explanation:
Initially, the Counter's internal state is 0. The parent component also shows 0 as the reset count because the reset hasn't happened yet.

Example 2: Resetting the Counter

Input:
- Counter's count is 5.
- App's "Reset Counter" button is clicked.

Output:
[In the browser]
--------------------------
Counter Component:
  Count: 0
  [Increment] button

App Component:
  [Reset Counter] button
  Reset Count: 0
--------------------------

Explanation:
Clicking "Reset Counter" in App calls the `reset` method on the Counter. The Counter's internal state becomes 0. The App then accesses `currentValue` (which is now 0) and updates its "Reset Count" display. The Counter also visually updates to show "Count: 0".

Constraints

  • All code must be written in TypeScript.
  • The solution should leverage React Hooks: useState, useRef, forwardRef, and useImperativeHandle.
  • Avoid direct DOM manipulation for updating the counter's display from the parent. The currentValue should be obtained via the ref.
  • The Counter component should be a functional component.

Notes

  • Think carefully about the types you'll need to define for the ref object when using forwardRef and useImperativeHandle.
  • The useImperativeHandle hook allows you to customize the instance value that is exposed when using ref.
  • Remember to import necessary hooks from react.
Loading editor...
typescript