Hone logo
Hone
Problems

Implementing a useList Hook for React

The useList hook provides a convenient way to manage a list of items in a React component, offering common operations like adding, removing, updating, and searching. This hook simplifies state management for list-based components, reducing boilerplate and improving code readability. Your task is to implement this hook, providing a robust and reusable solution for managing lists in your React applications.

Problem Description

You need to implement a custom React hook called useList. This hook should accept an initial list of items as an argument and return an object containing functions to manipulate that list. The returned object should include the following functions:

  • list: The current list of items.
  • add: A function that adds a new item to the end of the list.
  • remove: A function that removes an item from the list based on its index.
  • update: A function that updates an item in the list at a given index with a new item.
  • search: A function that filters the list based on a search term. The search should be case-insensitive and check if the search term exists within any string property of the list items. If no matching property is found, the item should not be included in the results.
  • clear: A function that clears the entire list.

The hook should use the useState hook internally to manage the list's state.

Key Requirements:

  • The hook must be written in TypeScript.
  • The initial list should be of a generic type T.
  • All functions should update the list state correctly and trigger a re-render.
  • The search function should handle empty search terms gracefully (returning the full list).
  • The remove and update functions should handle out-of-bounds indices gracefully (e.g., by doing nothing or throwing an error - your choice, but document it).

Expected Behavior:

The hook should provide a clean and intuitive API for managing lists. The list property should always return the current state of the list. The other functions should modify the list state and trigger a re-render of the component using the hook.

Edge Cases to Consider:

  • Empty initial list.
  • Adding items to an empty list.
  • Removing items from an empty list.
  • Updating items in an empty list.
  • Searching for an empty string.
  • Invalid indices for remove and update.
  • List items with different data types.

Examples

Example 1:

Input: useList<string>(['apple', 'banana', 'cherry'])
Output: {
  list: ['apple', 'banana', 'cherry'],
  add: (newItem: string) => void,
  remove: (index: number) => void,
  update: (index: number, newItem: string) => void,
  search: (searchTerm: string) => string[],
  clear: () => void
}
Explanation: The hook is initialized with a list of strings. The returned object contains functions to manipulate this list.

Example 2:

Input: useList<number>([]);
Output: {
  list: [],
  add: (newItem: number) => void,
  remove: (index: number) => void,
  update: (index: number, newItem: number) => void,
  search: (searchTerm: string) => number[],
  clear: () => void
}
Explanation: The hook is initialized with an empty list of numbers.

Example 3:

Input: useList<{ id: number, name: string }>([{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]);
searchTerm: 'a'
Output: [{ id: 1, name: 'Alice' }]
Explanation: The search function filters the list, returning only the item where the 'name' property contains 'a' (case-insensitive).

Constraints

  • The hook must be implemented using React's useState hook.
  • The remove and update functions should handle indices outside the bounds of the list by doing nothing. This behavior should be documented.
  • The search function should perform a case-insensitive search across all string properties of the list items.
  • The hook should be generic, accepting a type parameter T for the list items.
  • The search term is a string.

Notes

  • Consider using the spread operator (...) for immutably updating the list when adding, removing, or updating items. This is crucial for React's change detection.
  • Think about how to handle potential errors or edge cases gracefully.
  • Document your code clearly, explaining the purpose of each function and any assumptions made.
  • The search function's behavior is key - ensure it correctly filters based on string properties.
  • Focus on creating a reusable and well-tested hook.
Loading editor...
typescript