reactjs - 为什么列表消失并且过滤不起作用?
问题描述
我向服务器发出请求并获取我在视图表列表中显示的数据(类别列表)并实现一些功能
我有一个任务,我应该如何处理列表:
title name
按用户输入名称类别input
并按下按钮时进行过滤Search
按标题名称过滤我可以使用查询参数来实现,当用户在输入中写入一些类别并按下按钮提交时q
,我将其插入到文件apiCategory.js
中
Example: http://path/q=animals
。
在这种情况下,页面上只会显示类别动物。
但是当我编写实现按title name
列表过滤的代码时,就消失了。并且过滤不起作用。
在代码中修复什么?
也许我在方法中写错了,filter
或者updateSearchInput
?
主页.js:
const Home = () => {
const [value, setValue] = useState({
listCategory: [],
filteredlistCategory: [],
searchInput: ""
});
useEffect(() => {
async function fetchData( searchInput ) {
const res = await apiCategory('/pathApi', {
method: 'GET',
}, searchInput);
setValue(prev => ({
...prev,
listCategory: res.data,
}));
}
fetchData(value.searchInput);
}, [value.searchInput]);
const updateSearchInput = (e) => {
setValue((prev) => ({
searchInput: e.target.value
}));
};
const filter = () => {
setValue((prev) =>
({ searchInput, listCategory}) => ({
filteredlistCategory: listCategory.filter(item =>
item.firstName.toLowerCase().includes(searchInput.toLowerCase()))
}))
};
return (
<div>
<Search value={value.searchInput} onChange={updateSearchInput} onSearch={filter}/>
<Table dataAttribute={value.filteredlistCategory}/>
</div>
);
};
apiCategory.js:
export const apiCategory = async (url, args, valueFilter) => {
const response = await fetch(`${url}?q=${valueFilter}`, {
...args,
headers: {/....}
}});
return response.json();
}
搜索.js:
export default ({ value, onChange, onSearch }) => {
return (
<div className="search">
<input type="text" className="searchInput" onChange={onChange} value={value}/>
<button className="buttonSearch" onClick={() => onSearch(value)}>Search</button>
</div>
);
};
来自服务器的响应:
{"data":[
{"id":1,"title":"animals","created_at":"/...","updated_at":"/..."},
{"id":2,"title":"space","created_at":"/...","updated_at":"/..."},
{"id":3,"title":"sport","created_at":"/...","updated_at":"/..."}
]
}
解决方案
我可以看到代码的一些问题:
- 在您的
fetchData
函数中,您没有设置filteredlistCategory
,而是将此列表传递给Table
组件,因此最初不会显示任何数据,因为列表是空的。 - 在
updateSearchInput
你没有保留旧值(listCategory
和filteredlistCategory
)。这可能就是列表消失的原因。它应该更像这样:
const updateSearchInput = (e) => {
const searchInput = e.target.value;
setValue((prev) => ({
...prev,
searchInput: searchInput
}));
};
- 过滤功能不正确,它包含提供给的双重功能
setValue
,您需要去掉其中一个。目前,您基本上是将函数设置为状态值,这会导致过滤不起作用。尝试这样的事情:
const filter = () => {
setValue((prev) => ({
...prev
filteredlistCategory: listCategory.filter(item =>
item.firstName.toLowerCase().includes(searchInput.toLowerCase())
)
}))
};
但是,在这种情况下,为了代码的清晰,我建议为每个属性创建单独的状态(3 useState
s 而不是 1),因此您不需要记住在仅更改其中一个时保留其他人的旧值他们。或者,尝试使用useReducer
钩子。
编辑:我对您的 Home.js 文件进行了一些更改,应该可以解决这些问题:
- 在对输入到搜索输入中的每个字符发出新的 API 请求之前 - 这是低效的,我已将其更改为仅在
filter
单击按钮后发出请求。它是通过从 中删除依赖关系来完成的useEffect
,因此它只在初始组件创建时运行一次,并在filter
函数中发出请求。 - 删除
filteredlistCategory
了属性,因为似乎没有必要在此组件内存储重复列表(数据总是从新搜索的服务器中获取)
const Home = () => {
const [value, setValue] = useState({
listCategory: [],
searchInput: ""
});
useEffect(() => {
fetchData(value.searchInput);
}, []);
const fetchData = async ( searchInput ) => {
const res = await apiCategory('/pathApi', {
method: 'GET',
}, searchInput);
setValue(prev => ({
...prev,
listCategory: res.data
}));
}
const updateSearchInput = (e) => {
const searchInput = e.target.value;
setValue((prev) => ({
...prev,
searchInput: searchInput
}));
};
const filter = async () => {
await fetchData(value.searchInput);
};
return (
<div>
<Search value={value.searchInput} onChange={updateSearchInput} onSearch={filter}/>
<Table dataAttribute={value.listCategory}/>
</div>
);
};
推荐阅读
- java - elasticsearch 6中的模糊建议
- android - 使用 Android Nougat 的共享内存进行媒体解码
- azure - Azure Functions - 事件中心触发器 - 测试版 /V2
- asp.net - 通过 CreateUserWizard 连接 SQL 数据库时出错
- php - 使用全局路由前缀时未找到 Laravel 页面错误
- sql-server-2008 - MS-access 直通查询到 SQL Server 2008 添加前缀
- python - Django 导入错误:无法导入名称“Shift”
- sql - 在sql中格式化日期
- java - 如何向 flink CEP 数据流添加新事件?
- neural-network - 仅针对单个对象的对象检测