Hone logo
Hone
Problems

Reactive Interruption System in React

This challenge focuses on building a reusable interruption system within a React application. Imagine you're developing a complex UI where certain actions need to be interrupted based on specific conditions (e.g., stopping a drag-and-drop operation when a modal opens, or halting a form submission when validation fails). This system will provide a clean and predictable way to manage these interruptions.

Problem Description

You are tasked with creating a React hook, useInterruption, that allows components to register interruption handlers and trigger them when an interruption occurs. The hook should manage a list of registered handlers and provide a mechanism to interrupt them.

What needs to be achieved:

  • Create a useInterruption hook that accepts an interrupt function as an argument. This interrupt function will be called to signal an interruption.
  • The hook should allow components to register interruption handlers using a registerHandler function returned by the hook.
  • Each registered handler should accept a callback function as an argument. This callback function will be executed when an interruption is triggered.
  • The hook should also provide a deregisterHandler function to remove previously registered handlers.
  • The hook should ensure that all registered handlers are executed sequentially when an interruption is triggered.

Key Requirements:

  • The useInterruption hook must be implemented using React's useState and useEffect hooks.
  • The registerHandler function should return a unique identifier for the registered handler. This identifier is needed for deregistration.
  • The interrupt function should trigger the execution of all registered handlers.
  • The deregisterHandler function should remove the handler associated with the provided identifier.
  • The handlers should be executed in the order they were registered.

Expected Behavior:

When interrupt() is called:

  1. Each registered handler's callback function should be executed.
  2. The execution of handlers should be sequential (one handler completes before the next starts).
  3. Deregistering a handler should prevent it from being executed in subsequent interruptions.

Edge Cases to Consider:

  • Calling interrupt() with no registered handlers should not cause any errors.
  • Calling deregisterHandler() with an invalid identifier should be handled gracefully (e.g., by doing nothing).
  • Handlers can be registered and deregistered multiple times.
  • Consider how to handle errors within a handler's callback function. Should errors stop the execution of subsequent handlers? (For this challenge, assume errors should not stop execution).

Examples

Example 1:

Input:
Component A registers handler 1 with callback function 'handlerA'.
Component B registers handler 2 with callback function 'handlerB'.
interrupt() is called.
Output:
handlerA() is executed.
handlerB() is executed.
Explanation:
The interrupt function triggers the execution of all registered handlers in the order they were registered.

Example 2:

Input:
Component A registers handler 1 with callback function 'handlerA'.
interrupt() is called.
Component A deregisters handler 1.
interrupt() is called again.
Output:
First interrupt: handlerA() is executed.
Second interrupt: No handlers are executed.
Explanation:
Deregistration prevents the handler from being executed in subsequent interruptions.

Example 3: (Edge Case)

Input:
interrupt() is called with no registered handlers.
Output:
No handlers are executed.
Explanation:
Calling interrupt with no registered handlers should not cause an error.

Constraints

  • The solution must be written in TypeScript.
  • The useInterruption hook should be reusable across different components.
  • The execution of handlers should be synchronous. Asynchronous operations within handlers are allowed, but the handlers themselves should execute sequentially.
  • The number of registered handlers should not exceed 100. (This is a practical limit to avoid performance issues in extreme cases).

Notes

  • Think about how to manage the state of registered handlers effectively.
  • Consider using a functional approach to handle the interruption logic.
  • The interrupt function should be exposed to components that need to trigger interruptions.
  • Focus on creating a clean and well-documented API for the useInterruption hook. The hook should be easy to understand and use.
  • Error handling within the handlers is not a primary focus of this challenge, but consider how it might be handled in a real-world application.
Loading editor...
typescript