Javascript 如何一次从多个URL获取数据?

Javascript 如何一次从多个URL获取数据?,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个函数,可以从React中的url获取 const DataContextProvider = (props) => { const [isLoading, setLoading] = useState(false); const [cocktails, setCocktails] = useState([]); useEffect(() => { const fetchCocktailList = async () => { const

我有一个函数,可以从React中的url获取

const DataContextProvider = (props) => {
  const [isLoading, setLoading] = useState(false);
  const [cocktails, setCocktails] = useState([]);

  useEffect(() => {
    const fetchCocktailList = async () => {
      const baseUrl = 'https://www.thecocktaildb.com/api/json/v1/1/';
      setLoading(true);
      try {
        const res = await fetch(`${baseUrl}search.php?s=margarita`);
        const data = await res.json();
        console.log(data);
        setCocktails(data.drinks);
        setLoading(false);
      } catch (err) {
        console.log('Error fetching data');

        setLoading(false);
      }
    };

    fetchCocktailList();
  }, []);


到目前为止,我是如何映射数据的

const DrinkList = () => {
  const { cocktails } = useContext(DataContext);
  return (
    <div className='drink-list-wrapper'>
      {cocktails.length > 0 &&
        cocktails.map((drink) => {
          return <DrinkItem drink={drink} key={drink.idDrink} />;
        })}
    </div>
  );
};
constdrinklist=()=>{
const{cocktails}=useContext(DataContext);
返回(
{cocktails.length>0&&
鸡尾酒。地图((饮料)=>{
返回;
})}
);
};
但是,我还想从这个url获取
${baseUrl}search.php?s=martini


我希望有一个很好的方法来完成这项工作,并将我的状态设置为两个返回的数据。

首先将数据获取函数基于一个参数:

const fetchCocktail = async (name) => {
  const baseUrl = 'https://www.thecocktaildb.com/api/json/v1/1/';
  try {
    const res = await fetch(`${baseUrl}search.php?s=` + name);
    const data = await res.json();
    return data.drinks;
  } catch (err) {
    console.log('Error fetching data');
  }
}
然后使用等待所有结果:

setLoading(true);
var promises = [
  fetchCocktail(`margarita`),
  fetchCocktail(`martini`)
];
var results = await Promise.all(promises);
setLoading(false);
DrinkList(results);

其中,
results
将是一个包含响应的数组,您可以在
DrinkList
函数中使用这些响应。

这里有一个方法,可以让您指定鸡尾酒名称作为
useffect
的依赖项,以便您可以将它们存储在您的状态中,并在需要新配方时获取新的饮料列表。如果不是,它将只是一个静态变量

  • 我还添加了另一个状态变量
    errorMessage
    ,用于在出现故障时传递错误消息
  • 也,。调用
    useState
    返回的
    setState
    函数是稳定的,不会触发效果的重新运行,
    cocktailNames
    变量不会触发重新运行,除非您使用要获取的新内容对其进行更新
constdatacontextprovider=(props)=>{
const[isLoading,setLoading]=useState(false);
const[cocktails,setCocktails]=useState([]);
const[errorMessage,setErrorMessage]=useState(“”);//在网络请求失败时保存错误消息
const[cocktailNames,setCocktailNames]=useState(['margarita','martini']);//在API端点处搜索's'参数
useffect(()=>{
const fetchCocktailList=异步(…cocktailNames)=>{
const fetchCocktailList=异步(cocktailName)=>{
常量baseUrl=https://www.thecocktaildb.com/api/json/v1/1/search.php';
const url=新的url(baseUrl);
const params=新的URLSearchParams({s:cocktailName});
url.search=params.toString();//->“?s=cocktailName”
const res=wait fetch(url.href);//->https://www.thecocktaildb.com/api/json/v1/1/search.php?s=cocktailName'
const data=wait res.json();
const{drinks:drinkList}=data;//解构形式为:const-drinkList=data.drinks;
返回饮酒者;
};
设置加载(真);
试一试{
常量承诺=[];
for(const cocktailName of cocktailNames){
promises.push(fetchCocktailList(cocktailName));
}
const drinkLists=等待承诺。所有(承诺);//->[[drink1,drink2],[drink3,drink4]]
const allDrinks=drinkLists.flat(1);//->[drink1,drink2,drink3,drink4]
设置鸡尾酒(所有饮料);
}
捕捉(错误){
setErrorMessage(err.message/*或任何您想要的自定义消息*/);
}
设置加载(假);
};
fetchCocktailList(…cocktailNames);
},[cocktailNames、setCocktails、setErrorMessage、setLoading]);
};
var承诺=[ 获取鸡尾酒(
api1
), 获取鸡尾酒(
api2
) ];
var结果=等待承诺。全部结算(承诺)

当您用该响应获取
martini
setCocktails
时,它是否应该替换
margarita
响应,或者您希望它将这些饮料添加到某个对象/数组中?它不应该替换。我想要鸡尾酒同时含有马提尼和玛格丽塔。所以我可以映射它们。您希望如何处理单个网络请求中的错误?如果一个请求失败,整个操作是否会失败?或者它是否会使用部分数据成功?好的,那么您是否也可以共享您的组件代码,这样我们就可以看到您的状态对象是什么样子的,以便
setCocktails
可以正确地合并到新饮料中?我的第一个问题是它是否会失败。然而,我正在学习,如果它的最佳实践是单独处理,那么我会这样做。这就是我要回答的,但要注意的是,
Promise.allsetted
将允许您处理混合成功/失败,而
Promise.all
将拒绝任何失败您可能也应该
设置加载(错)
在为cleanupNevermind编写的
finally
中的try/catch之后,您不断更改代码。在您完成所有编辑之前,我将停止评论。@jsejcksn finished:我已尝试过此操作并使浏览器崩溃。可能是因为useEffect钩子导致无限循环?这在快速复制和粘贴以进行检查后有效。但是让我感到尴尬的是,我不了解其中的一些部分。比如URLSearchParams,使用.flat ect,而且永远无法向任何人解释它!有没有办法将其剥离到一个更适合初学者的级别?它是以可扩展的方式编写的,并且作为学习的模型。对于更硬编码的ap,肯定有一些部分可以简化方法,但这是您真正想要的吗?
URLSearchParams
为您处理搜索参数的编码。如果您想添加更多参数,只需添加到构造函数调用中的对象参数。
array.flat()
只要将多维数组展平,不管你要求它达到多个级别。请查看关于这两个级别的MDN文章,以进一步了解它们。我将在代码中添加一些注释。祝你好运!一些React概念可能有点让人挠头。Docs,Docs,Docs。。。