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
searchfunction should handle empty search terms gracefully (returning the full list). - The
removeandupdatefunctions 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
removeandupdate. - 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
useStatehook. - The
removeandupdatefunctions should handle indices outside the bounds of the list by doing nothing. This behavior should be documented. - The
searchfunction should perform a case-insensitive search across all string properties of the list items. - The hook should be generic, accepting a type parameter
Tfor 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
searchfunction's behavior is key - ensure it correctly filters based on string properties. - Focus on creating a reusable and well-tested hook.