我正在实现一个搜索功能,其中输入框将搜索具有以下字段的用户列表。
id:一个唯一的id name: 用户名 items:用户订购的商品列表 地址:用户的地址 密码:用户地址密码
需要对所有字段数据实施搜索。
数据:http://www.mocky.io/v2/5ba8efb23100007200c2750c
问题:搜索结果很荒谬,例如搜索“Jo”也会显示“Ja”和“12”的结果也会显示“aa”和“32”的结果
搜索框组件:
import React, { useState, useRef, useEffect } from 'react'
import '../stylesheets/searchbar.css';
import Card from './Card';
export default function SearchBar({ placeholder, data }) {
const [searchInput, setSearchInput] = useState('');
const [filteredResult, setFilteredResult] = useState([]);
const [searching, setSearching] = useState(false);
const handleSearch = (event) => {
const value = event.target.value;
if (value.length === 0) {
setFilteredResult([])
setSearching(false);
}
if (value?.length > 0) {
searchItems(value);
setSearching(true);
}
}
const searchItems = (searchValue) => {
setSearchInput(searchValue);
if (searchInput.length !== 0) {
const filteredData = data.filter((item) => {
return Object.values(item).join(' ').toLowerCase().includes(searchInput.toLowerCase());
});
setFilteredResult(filteredData);
}
};
return (
<div className='search'>
<div className='searchInput'>
<input type="text" placeholder={placeholder} data={data} onChange={handleSearch} />
</div>
{
filteredResult?.length > 0 ? (
<div className='searchResult'>
{filteredResult.map(({ id, name, address }, i) => (
<Card key={id} id={id} name={name} address={address} searchInput={searchInput} filteredResult={filteredResult} />
))}
</div>
) : (
<div>
{searching ? (
<div className='searchResult'>No user found</div>
) : (
null
)}
</div>
)
}
</div>
)
}
预期:
在这一行之后
setFilteredResult(filteredData);
添加
console.log(`searchInput: '${searchInput}'`)
console.log(JSON.stringify(filteredData, null, 2))
这将使您能够检查对于“Ja”的
searchInput
意外出现的情况是否恰好在其中一个属性内的某处有“Ja”,例如在地址或个人密码中。
如果您不想在搜索中包含某些属性,请仅包含您想要的属性。
例如,您可能想搜索唯一的用户 ID。
searchInput
日志,紧接在输出之上,说了什么?我问是因为你举的例子绝对不符合
123
。因此 searchInput
一定不是 123,而是其他东西。也许只有 12 甚至 1?打印出来的是什么?
将循环内的
searchInput
改为searchValue
。
据此:
https://beta.reactjs.org/reference/react/useState
陷阱调用 set 函数不会改变已执行代码中的当前状态:
function handleClick() { setName('罗宾');控制台日志(名称); // 还是“泰勒”!它只影响 useState 将返回的开始 来自下一个渲染。