Skip to content

Instantly share code, notes, and snippets.

@dilipsuthar97
Last active June 14, 2025 13:49
Show Gist options
  • Save dilipsuthar97/980dde43fd96ffe666897bbe5bba403b to your computer and use it in GitHub Desktop.
Save dilipsuthar97/980dde43fd96ffe666897bbe5bba403b to your computer and use it in GitHub Desktop.
A custom hook function to search data in list of objects, it supports 2 nested objects
import { useState, useEffect, useMemo } from 'react';
// Helper function to get nested value from object by dot notation
const getValueByPath = (obj: any, path: string): any => {
return path.split('.').reduce((acc, key) => acc?.[key], obj);
};
/**
* Returns a filtered dataset and a function to update the main data source.
*
* @param {String} query - Search query.
* @param {Array} keysToSearch - Dot notation keys to search for value.
*/
export default function useFilteredData<T>(query: string, keysToSearch: string[]) {
const [data, setData] = useState<T[]>([]);
const [filteredData, setFilteredData] = useState<T[]>([]);
const [isDataReady, setIsDataReady] = useState(false);
useEffect(() => {
const lowerQuery = query.toLowerCase();
const result = data.filter(item =>
keysToSearch.some(key => {
const value = getValueByPath(item, key);
return (value ?? '').toString().toLowerCase().includes(lowerQuery);
})
);
setFilteredData(result);
setIsDataReady(true);
}, [query, data, keysToSearch]);
return useMemo(() => ({
filteredData,
setData,
data,
isDataReady,
}), [filteredData, data, isDataReady]);
}
// ✅ Usage Example
const [searchKeyword, setSearchKeyword] = useState('');
const { filteredData, setData } = useFilteredData(searchKeyword, ['name.common']);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment