Hone logo
Hone
Problems

Implement a useStack Custom Hook for Managing Stack Data in React

This challenge asks you to create a custom React hook called useStack that provides a simple and intuitive way to manage a stack data structure within your React components. A stack is a Last-In, First-Out (LIFO) data structure, and a hook for it can be incredibly useful for scenarios like managing undo/redo functionality, navigation history, or temporary state.

Problem Description

You need to implement a custom React hook useStack that returns an object with methods to interact with a stack. The hook should:

  • Initialize: Accept an optional initial array of items to populate the stack.
  • Provide State: Expose the current state of the stack (an array of items).
  • Offer Core Operations:
    • push(item): Adds an item to the top of the stack.
    • pop(): Removes and returns the item from the top of the stack. If the stack is empty, it should return undefined.
    • peek(): Returns the item at the top of the stack without removing it. If the stack is empty, it should return undefined.
    • isEmpty(): Returns a boolean indicating whether the stack is empty.
    • clear(): Removes all items from the stack.
  • Handle Updates: Ensure that when the stack state changes (via push, pop, or clear), components using the hook re-render to reflect the updated stack.

Examples

Example 1:

import React from 'react';
import { useStack } from './useStack'; // Assuming your hook is in './useStack.ts'

function StackComponent() {
  const { stack, push, pop, peek, isEmpty } = useStack<number>([1, 2]);

  return (
    <div>
      <p>Stack: {JSON.stringify(stack)}</p>
      <button onClick={() => push(3)}>Push 3</button>
      <button onClick={() => pop()}>Pop</button>
      <button onClick={() => alert(`Top item: ${peek()}`)}>Peek</button>
      <p>Is Empty: {isEmpty() ? 'Yes' : 'No'}</p>
    </div>
  );
}

// Initial Render:
// Stack: [1,2]
// Is Empty: No

// After clicking "Push 3":
// Stack: [1,2,3]
// Is Empty: No

// After clicking "Pop":
// Stack: [1,2]
// Is Empty: No

// After clicking "Peek": (Alert shows "Top item: 3")

Example 2:

import React from 'react';
import { useStack } from './useStack';

function EmptyStackComponent() {
  const { stack, push, pop, isEmpty, clear } = useStack<string>();

  return (
    <div>
      <p>Stack: {JSON.stringify(stack)}</p>
      <button onClick={() => push('hello')}>Push "hello"</button>
      <button onClick={() => pop()}>Pop</button>
      <button onClick={() => clear()}>Clear</button>
      <p>Is Empty: {isEmpty() ? 'Yes' : 'No'}</p>
    </div>
  );
}

// Initial Render:
// Stack: []
// Is Empty: Yes

// After clicking "Push 'hello'":
// Stack: ["hello"]
// Is Empty: No

// After clicking "Pop":
// Stack: []
// Is Empty: Yes

// After clicking "Clear" on a non-empty stack:
// Stack: []
// Is Empty: Yes

Example 3: Popping from an empty stack

import React from 'react';
import { useStack } from './useStack';

function EmptyPopComponent() {
  const { stack, pop, peek } = useStack<number>();

  return (
    <div>
      <p>Stack: {JSON.stringify(stack)}</p>
      <button onClick={() => alert(`Popped: ${pop()}`)}>Pop</button>
      <button onClick={() => alert(`Peeked: ${peek()}`)}>Peek</button>
    </div>
  );
}

// Initial Render:
// Stack: []

// After clicking "Pop": (Alert shows "Popped: undefined")
// Stack: []

// After clicking "Peek": (Alert shows "Peeked: undefined")
// Stack: []

Constraints

  • The hook must be implemented using TypeScript.
  • The hook should use React's useState hook internally to manage the stack's state.
  • The provided methods (push, pop, peek, isEmpty, clear) should be pure functions where possible, but pop and clear will necessarily update state.
  • The hook should be generic, allowing it to manage stacks of any data type.

Notes

  • Consider how you will handle state updates to ensure React re-renders correctly.
  • Think about the return type of your hook and what information a component using it will need.
  • The pop and peek operations should correctly return undefined when the stack is empty, as this is standard behavior for stack implementations.
Loading editor...
typescript