Hone logo
Hone
Problems

Create a Reusable useBoolean Hook in React

This challenge asks you to create a custom React hook called useBoolean. This hook will encapsulate common boolean state management logic, making it easier to toggle and reset boolean values within your React components. This is a fundamental building block for managing UI states like toggles, modals, and loading indicators.

Problem Description

You need to implement a TypeScript React hook named useBoolean. This hook should manage a single boolean state and provide functions to manipulate that state.

Key Requirements:

  1. Initialization: The hook should accept an optional initial boolean value. If no initial value is provided, it should default to false.
  2. State Management: The hook should return an array containing:
    • The current boolean state value.
    • A function to toggle the boolean value (from true to false and vice-versa).
    • A function to set the boolean value to true.
    • A function to set the boolean value to false.
    • A function to reset the boolean value to its initial state.
  3. Typing: The hook and its returned functions should be properly typed using TypeScript.

Expected Behavior:

When useBoolean is called with an initial value, the returned state should reflect that initial value. Calling the toggle function should flip the current state. Calling setTrue should set the state to true. Calling setFalse should set the state to false. Calling reset should restore the state to the value it had when useBoolean was first called.

Edge Cases to Consider:

  • Calling useBoolean without any arguments.
  • The reset function should correctly restore the state even after multiple toggles, sets, or resets.

Examples

Example 1:

import { useBoolean } from './useBoolean'; // Assuming useBoolean is in a file named useBoolean.ts

function MyComponent() {
  const [isToggled, toggle, setTrue, setFalse, reset] = useBoolean(false);

  return (
    <div>
      <p>Is toggled: {isToggled ? 'Yes' : 'No'}</p>
      <button onClick={toggle}>Toggle</button>
      <button onClick={setTrue}>Set True</button>
      <button onClick={setFalse}>Set False</button>
      <button onClick={reset}>Reset</button>
    </div>
  );
}

Output: When the component initially renders, "Is toggled: No" is displayed.

  • Clicking "Toggle" changes it to "Is toggled: Yes".
  • Clicking "Toggle" again changes it back to "Is toggled: No".
  • Clicking "Set True" changes it to "Is toggled: Yes".
  • Clicking "Set False" changes it to "Is toggled: No".
  • Clicking "Reset" after any sequence of operations will set it back to "Is toggled: No" (its initial value).

Example 2:

import { useBoolean } from './useBoolean';

function AnotherComponent() {
  const [isLoading, toggleLoading, turnOn, turnOff, resetLoading] = useBoolean(true);

  return (
    <div>
      <p>Loading: {isLoading ? 'Currently loading...' : 'Data loaded!'}</p>
      <button onClick={toggleLoading}>Toggle Loading</button>
      <button onClick={turnOff}>Stop Loading</button>
      <button onClick={resetLoading}>Reset Loading State</button>
    </div>
  );
}

Output: When the component initially renders, "Loading: Currently loading..." is displayed.

  • Clicking "Toggle Loading" changes it to "Loading: Data loaded!".
  • Clicking "Stop Loading" changes it to "Loading: Data loaded!".
  • Clicking "Reset Loading State" will set it back to "Loading: Currently loading..." (its initial value).

Example 3: No Initial Value

import { useBoolean } from './useBoolean';

function DefaultComponent() {
  const [isActive, toggleActive] = useBoolean(); // No initial value provided

  return (
    <div>
      <p>Active: {isActive ? 'Yes' : 'No'}</p>
      <button onClick={toggleActive}>Toggle Active</button>
    </div>
  );
}

Output: When the component initially renders, "Active: No" is displayed (defaults to false).

  • Clicking "Toggle Active" changes it to "Active: Yes".
  • Clicking "Toggle Active" again changes it back to "Active: No".

Constraints

  • The solution must be implemented in TypeScript.
  • The hook must be a functional React hook.
  • The hook should utilize useState internally for state management.
  • The returned functions should be stable (i.e., not re-created on every render unless their dependencies change, though for this hook, they won't).

Notes

  • Consider how to handle the initial value and the reset function's behavior correctly.
  • Think about the return type of your hook and how to destructure the returned array effectively in your components.
  • The names of the returned functions are flexible, but they should clearly indicate their purpose (e.g., toggle, setTrue, setFalse, reset).
Loading editor...
typescript