#javascript #reactjs #search #filter
#javascript #reactjs #Поиск #Фильтр
Вопрос:
Я пытаюсь создать поиск с фильтрацией в реальном времени для длинного списка элементов, элементы представлены в виде массива, содержащего массивы со строкой и объектом, как:
const items = [
["cats", [
{name: "name", img: "img/img.jpg"},
{name: "name2", img: "img2/img.jpg"},
...
]],
["dogs", [
{name: "name", img: "img/img.jpg"},
{name: "name2", img: "img2/img.jpg"},
...
]],
...
]
и я пытаюсь отфильтровать его по значениям имен.
Что я пробовал, так это:
export default function Page({ items }) {
const [searchTerm, setSearchTerm] = React.useState("");
const [searchResults, setSearchResults] = React.useState(items);
const handleChange = event => {
setSearchTerm(event.target.value);
}
useEffect(() => {
var f=0, results = []
while (f < items.length){
if(items[f][1].includes(searchTerm)){
results.push(result)
}
f
}
setSearchResults(results);
}, [searchTerm]);
return (
<div>
<input
type="text"
placeholder="Search"
value={searchTerm}
onChange={handleChange}
/>
{searchResults.map((cl, index) => (
<div key={index}>
<h2>{cl[0]}</h2>
<ScrollContainer>
{cl[1].map((item, i) => (
<h3>{item.name}</h1>
))}
</ScrollContainer>
</div>
))}
но он выдает ошибку:
Ошибка ChunkLoadError: не удалось загрузить фрагмент 0.
Комментарии:
1. Не используйте
index
в качестве ключа для итерацииmap
функции. это снижает скорость вашего приложения, а также является причиной странных ошибок. reactjs будет использовать его для сравнения, добавив к нему уникальное строковое имя из элементов вашего массива.
Ответ №1:
Прежде всего, пожалуйста, исправьте вашу модель данных. когда он числится, так почему вы использовали массив массива, поверните его так:
const items = [
{ name: "name", img: "img/img.jpg", type: "cat" },
{ name: "name2", img: "img2/img.jpg", type: "cat" },
...
{ name: "name", img: "img/img.jpg", type: "dog" },
{ name: "name2", img: "img2/img.jpg", type: "dog" },
...
]
А что касается вашего поиска в реальном времени, используйте fuse.js
, вы можете добавить его в свой проект и с помощью простой конфигурации отфильтровать для вас, особенно fuse.js
очень удобно с приведенной выше моделью данных. просто попробуйте. вы будете довольны этим.
Ответ №2:
Я бы предложил исправить ваши данные, как сказал Амерлика, но если у вас есть текущий формат данных, подобный этому, вы можете преобразовать его следующим образом.
const items = [
["cats", [
{name: "name", img: "img/img.jpg"},
{name: "name2", img: "img2/img.jpg"},
]],
]
const object = Object.fromEntries(items);
это преобразует ваши данные следующим образом:
{
"cats":[{"name":"name","img":"img/img.jpg"},{"name":"name2","img":"img2/img.jpg"}]
}
итак, если вы хотите найти кошек или собак
вы можете сделать это:
const searchTerm = 'cats'
const foundKey = Object.keys(object).find(key => key === searchTerm)
const foundObject = object[foundKey];
Вывод foundObject будет:
"[{"name":"name","img":"img/img.jpg"},{"name":"name2","img":"img2/img.jpg"}]"
и если вы хотите найти конкретное имя для кошки, это будет выглядеть так
const searchNameOfFoundObject = 'name';
const findNameOfFoundObject = foundObject.find(value => value.name === searchNameOfFoundObject)
тогда вывод объекта findNameOfFoundObject будет:
{"name":"name","img":"img/img.jpg"}
Но я предлагаю вам выполнить поиск в бэкэнде, если это большие данные, это будет бременем для вашего интерфейса, это замедлит работу вашего приложения. Вы должны просто отправить поисковый запрос в API, и данные, которые вам понадобятся на основе поискового запроса, будут ответом api. это будет обрабатываться намного быстрее на серверной части, и ваше интерфейсное приложение react будет более оптимизированным и удобным для пользователя.