簡體   English   中英

如何一次從多個網址獲取數據?

[英]How to fetch data from multiple urls at once?

我有一個從 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>
  );
};

但是我也想從這個 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');
  }
}

然后使用Promise.all等待所有結果:

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

results將是一個包含您可以在DrinkList函數上使用的響應的數組。

這是一個方法,它可以讓您指定雞尾酒名稱作為useEffect依賴項,以便您可以將它們存儲在您的狀態中,並在您需要新食譜時獲取新的飲料清單。 如果沒有,它將只是一個靜態變量。

  • 我還添加了另一個狀態變量errorMessage用於在失敗的情況下傳遞錯誤消息。
  • 此外,您應該在useEffect hook 中包含適當的依賴useEffect 調用useState返回的setState函數是穩定的,不會觸發重新運行效果,並且除非您使用要獲取的新內容更新它,否則cocktailNames變量不會觸發重新運行。
const DataContextProvider = (props) => {
  const [isLoading, setLoading] = useState(false);
  const [cocktails, setCocktails] = useState([]);
  const [errorMessage, setErrorMessage] = useState(''); // holds an error message in case the network request dosn't succeed
  const [cocktailNames, setCocktailNames] = useState(['margarita', 'martini']); // the search queries for the `s` parameter at your API endpoint

  useEffect(() => {
    const fetchCocktailLists = async (...cocktailNames) => {
      const fetchCocktailList = async (cocktailName) => {
        const baseUrl = 'https://www.thecocktaildb.com/api/json/v1/1/search.php';
        const url = new URL(baseUrl);
        const params = new URLSearchParams({s: cocktailName});
        url.search = params.toString(); // -> '?s=cocktailName'
        const res = await fetch(url.href); // -> 'https://www.thecocktaildb.com/api/json/v1/1/search.php?s=cocktailName'
        const data = await res.json();
        const {drinks: drinkList} = data; // destructured form of: const drinkList = data.drinks;
        return drinkList;
      };

      setLoading(true);
      try {
        const promises = [];
        for (const cocktailName of cocktailNames) {
          promises.push(fetchCocktailList(cocktailName));
        }
        const drinkLists = await Promise.all(promises); // -> [[drink1, drink2], [drink3, drink4]]
        const allDrinks = drinkLists.flat(1); // -> [drink1, drink2, drink3, drink4]
        setCocktails(allDrinks);
      }
      catch (err) {
        setErrorMessage(err.message /* or whatever custom message you want */);
      }
      setLoading(false);
    };

    fetchCocktailList(...cocktailNames);
  }, [cocktailNames, setCocktails, setErrorMessage, setLoading]);
};

var promises = [ fetchCocktail( api1 ), fetchCocktail( api2 ) ]; var 結果 = 等待 Promise.allSettled(promises);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM