我正在尝试使用来自 API 调用的名称填充选择栏。我已经创建了我的钩子,也使用了它的副作用,并将数据向下传递。它给我的地图不是函数错误。我的变量是一个空数组,但变量的设置者没有将值分配给我的变量。如何清除地图而不是功能错误?我附上了我的片段。谢谢。
import React, { useEffect, useState } from "react";
import axios from "axios";
const Sidebar = () => {
const [ingredients, setIngredients] = useState([]);
useEffect(() => {
const fetchIngredients = async (url) => {
try {
let res = await axios.get(url);
setIngredients(res.data);
} catch (error) {
setIngredients([]);
console.log(error);
}
};
fetchIngredients(
"https://www.thecocktaildb.com/api/json/v2/1/search.php?i=vodka"
);
}, []);
const displayIngredients = ingredients.map((ingredient) => {
setIngredients(ingredient.name);
return <option key={ingredient.name}>{ingredients}</option>;
});
return (
<div className="sidebar">
<label>
By ingredient:
<select>{displayIngredients}</select>
</label>
</div>
);
};
export default Sidebar
答案 0 :(得分:2)
首先,这里
setIngredients(res.data);
将 res.data
更改为 res.ingredients
(响应对象没有 data
属性)。然后你会面临另一个错误,
const displayIngredients = ingredients.map((ingredient) => {
setIngredients(ingredient.name);
//...
首先,ingredient.name
是未定义的,其次,如果它存在,它可能是一个字符串。只需在此处放弃 setIngredients
调用。
答案 1 :(得分:1)
您将 displayIngredients
声明为数组的变量 typeof(通过直接影响 array.map() 结果)。你需要它是一个返回数组的函数,如下所示:
const displayIngredients = () => ingredients.map((ingredient) => {
// Do not erase your previous values here
setIngredients(previousState => [...previousState, ingredient.name]);
// Changed it here as well, seems more logic to me
return <option key={ingredient.name}>{ingredient.name}</option>;
});
您还应该等待 API 调用结束,然后再显示您的选择,以防止数据加载时出现空白结果(如果有很多)。最简单的方法是在 API 调用运行时返回一个加载器:
if(!ingredients.length) {
return <Loader />; // Or whatever you want
}
return (
<div className="sidebar">
<label>
By ingredient:
<select>{displayIngredients}</select>
</label>
</div>
);