Исходя из ваших данных, начальное значение searchResults
- это словарь с ключом accounts
. Но когда вы обновляете его в части useEffect
, он изменяется на список:
useEffect(() => {
if (searchTerm) {
const results = searchResults.accounts.filter((c => c.name.toLowerCase().includes(searchTerm)))
// This changes the value of searchResults to an array
setSearchResults(results)
}
}, [searchTerm])
Когда setSearchResults
вызывается внутри useEffect
, значение searchResults
изменяется от объекта в массив:
из этого:
searchResults = {account: [...]}
в это:
searchResults = [.. .]
Именно поэтому он вызывает TypeError: Cannot read property 'filter' of undefined
после первого поиска, поскольку ключа accounts
больше нет.
Чтобы это исправить, необходимо быть согласованным в типе данных ваш searchResults
, было бы лучше сделать его в виде списка в первую очередь. Вы можете сделать это в onCompleted
part:
const { loading } = useQuery(GET_ACCOUNTS, {
fetchPolicy: "no-cache",
skip: userType !== 'OS_ADMIN',
onCompleted: (data) => setSearchResults(data.accounts || [])
});
Обратите внимание, что мы установили searchResults
в значение accounts
. После этого вам также понадобится способ доступа к searchResults
{searchResults &&
searchResults.map(c => {
return (
...renderhere
)
})
}
И ваш useEffect
будет выглядеть так:
useEffect(() => {
if (searchTerm) {
const results = searchResults.filter((c => c.name.toLowerCase().includes(searchTerm)))
setSearchResults(results)
}
}, [searchTerm])
СОВЕТ:
Вы можете переименовать ваш searchResults
в accounts
, чтобы сделать его более понятным. Учтите также, что после первого поиска ваши параметры будут ограничены предыдущим результатом поиска, поэтому вы можете также сохранить все учетные записи в другой переменной:
const [allAccounts, setAllAccounts] = useState([])
const [searchedAccounts, setSearchedAccounts] = useState([])
// useQuery
const { loading } = useQuery(GET_ACCOUNTS, {
fetchPolicy: "no-cache",
skip: userType !== 'OS_ADMIN',
onCompleted: (data) => {
setAllAccounts(data.accounts || [])
setSearchedAccounts(data.accounts || [])
}
});
// useEffect
useEffect(() => {
if (searchTerm) {
// Notice we always search from allAccounts
const results = allAccounts.filter((c => c.name.toLowerCase().includes(searchTerm)))
setSearchedAccounts(results)
}
}, [searchTerm])