我的问题是,我试图使用useEffect和useState挂钩在第一个渲染上显示数据(项目列表),并且在渲染之后我想过滤这些映射的项目。
当我进入商品页面时,在页面上呈现的商品为零。而且只有在我过滤掉它们之后(通过搜索过滤器或通过从选择下拉列表中选择所需的颜色),它们才会呈现。
下面我显示我的代码:
...
var [searchTerm, setSearchTerm] = useState<any>("");
var [searchResults, setSearchResults] = useState<any>([]);
const handleInput = (e: any) => {
console.log(e.target.value);
setSearchTerm(e.target.value);
};
var [pickedColor, setPickedColor] = useState<any>("");
var [colorPickResults, setColorPickResults] = useState<any>([]);
const handleColorChange = (e: any) => {
console.log(e.target.value);
setPickedColor(e.target.value);
};
var [items, setItems] = useState<any>([]);
useEffect(() => {
var message: string = "";
var fetchItems = () => {
axios
.get("/api/products")
.then((res: any) => {
console.log("res :", res);
setItems(res.data.data[0].products);
console.log("res.data.data[0].products :", res.data.data[0].products);
if (res.status === 200) {
message = "Products successfuly fetched.";
console.log(message);
} else {
message = "Something went wrong. Please try again later.";
console.log(message);
}
})
.catch((err: any) => console.log(err));
};
fetchItems();
const resultsFromSearch = items.filter((item: any) =>
item.title.toLowerCase().includes(searchTerm)
);
setSearchResults(resultsFromSearch);
const resultsFromPickedColor = resultsFromSearch.filter((item: any) =>
item.color.toLowerCase().includes(pickedColor)
);
setColorPickResults(resultsFromPickedColor);
}, [searchTerm, pickedColor]);
var filteredItems = colorPickResults;
var itemList = filteredItems.map((item: any) => {
return (
<div key={item.id} style={{ width: "370px", padding: "1rem" }}>
...
我在控制台中收到成功消息,并且如上所述成功提取了项目。
我尝试过的方法: 1.在[searchTerm,pickedColor,items]数组中添加“ items”,但是useEffect在获取项目时会创建无限循环,并在每次获取时重新渲染组件。
我可以更改些什么以获取帖子开头提到的所需功能? 我是否应该添加其他钩子,例如useContext,useMemo?或者,也许我可以以某种方式将获取与过滤分开?
答案 0 :(得分:0)
调用异步函数并尝试访问它会在以后返回的数据将永远无法按您期望的方式工作
fetchItems();
const resultsFromSearch = items.filter((item: any) =>
item.title.toLowerCase().includes(searchTerm)
);
您应该将该代码添加到.then
内的fetchItems
或可能有单独的useEffect
:
useEffect(() => {
const resultsFromSearch = items.filter((item: any) =>
item.title.toLowerCase().includes(searchTerm)
);
setSearchResults(resultsFromSearch);
}, [items])
对我来说,第二个选项更具声明性和灵活性,但这取决于您