Hone logo
Hone
Problems

Implementing a useMap Hook in React

The useMap hook is a custom React hook designed to manage and update a map (represented as a JavaScript object) within a functional component. This hook provides a centralized and reactive way to handle map data, ensuring that changes to the map trigger re-renders and maintain consistency across your component. This is particularly useful when dealing with dynamic data that needs to be associated with keys.

Problem Description

You are tasked with creating a useMap hook in React with TypeScript. This hook should accept an initial map (an object where keys are strings and values can be of any type) as an argument and return an object containing:

  1. map: The current state of the map.
  2. setMap: A function to update the entire map.
  3. set: A function to update a single key-value pair in the map. If the key already exists, the value should be updated. If the key doesn't exist, it should be added.
  4. delete: A function to remove a key-value pair from the map.

The hook should utilize the useState hook to manage the map's state and ensure that changes trigger re-renders. The set function should be optimized to avoid unnecessary re-renders when the value for a key doesn't change.

Key Requirements:

  • The hook must be written in TypeScript.
  • The initial map should be optional (default to an empty object).
  • The set function should merge the new key-value pair with the existing map.
  • The delete function should remove the specified key from the map.
  • The hook should handle potential errors gracefully (though explicit error handling isn't required for this challenge, consider how you might handle unexpected input types).

Expected Behavior:

  • The map property should always reflect the current state of the map.
  • Calling setMap should replace the entire map with the new map.
  • Calling set with a new key-value pair should add the pair to the map.
  • Calling set with an existing key should update the value associated with that key.
  • Calling delete with a key should remove the key-value pair from the map.
  • Changes to the map should trigger re-renders of the component using the hook.

Examples

Example 1:

Input: Initial map: { 'a': 1, 'b': 2 }
Output: {
  map: { 'a': 1, 'b': 2 },
  set: (newMap) => {},
  set: (key, value) => {},
  delete: (key) => {}
}
Explanation: The hook initializes with the provided map and returns the state management functions.

Example 2:

Input:  Component uses the hook, then calls set('c', 3), then set('a', 4)
Output: map state changes to { 'a': 4, 'b': 2, 'c': 3 }
Explanation: 'c' is added, and 'a' is updated.

Example 3: (Edge Case - Deletion)

Input: Component uses the hook, then calls delete('b')
Output: map state changes to { 'a': 1 }
Explanation: The key 'b' and its associated value are removed from the map.

Constraints

  • The initial map can be an empty object or contain any number of key-value pairs.
  • Keys in the map must be strings.
  • Values in the map can be of any type.
  • The set function should accept a single argument: either a new map object or a key-value pair (key as string, value as any).
  • The delete function should accept a single argument: the key to delete (string).
  • Performance: Avoid unnecessary re-renders when the value for a key remains unchanged after calling set.

Notes

  • Consider using the spread operator (...) to efficiently update the map.
  • Think about how to handle the different ways the set function can be called (either setting the entire map or setting a single key-value pair).
  • This hook is intended for simple map management. For more complex scenarios, consider using a dedicated state management library.
  • Focus on creating a clean, readable, and well-typed implementation.
Loading editor...
typescript