Как получить данные из нескольких URL-адресов одновременно? - PullRequest
3 голосов
/ 14 февраля 2020

У меня есть функция, которая извлекает из URL в React

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

Я хотел бы получить хороший чистый способ сделать это и установить мое состояние для обоих возвращаемых данных.

Ответы [ 3 ]

4 голосов
/ 14 февраля 2020

Сначала основывайте функцию выборки данных на параметре:

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.

0 голосов
/ 14 февраля 2020

var promises = [fetchCocktail (api1), fetchCocktail (api2)]; var results = await Promise.allSettled (обещания);

0 голосов
/ 14 февраля 2020

Вот метод, который позволит вам указать названия коктейлей как зависимости от useEffect, чтобы вы могли хранить их в своем штате и получать новые списки напитков, если вы хотите новые рецепты. Если нет, то это будет просто переменная состояния c.

  • Я также добавил еще одну переменную состояния errorMessage, которую вы используете для передачи сообщения об ошибке в случае сбоя.
  • Также, вы должны включить соответствующие зависимости в ваш useEffect хук . Функции setState, возвращаемые вызовами useState, стабильны и не будут запускать повторный запуск эффекта, а переменная 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]);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...