@rusrich

Как в React выполнить последовательно асинхронные функции?

Добрый день.

У меня две асинхронные функции получают данные через fetch.
Первая функция получает данные и записывает в State.
Вторая функция получает данные на основе записанных первой функцией данных в State и записывает их в другой State.

При загрузке страницы данные от первой функции в стейте находятся от второй нет.
Если сделать изменения в коде и сервер перезагрузится, то данные от второй функции в стейте появляются.

Подскажите решение.

Код ниже:
import React, { useEffect, useState } from 'react';
import { getCategories, getCollections, singleCategory } from "../../actions/category";
import Link from "next/link";

const Collect = ({ router }) => {
  const [ categories, setCategories ] = useState([])
  const [ collections, setCollections ] = useState([])
  const [ values, setValues ] = useState({
    error: '',
    success: '',
    loaded: false
  })

  useEffect(() => {
    initCategories()
    getCollect()

  }, [])


  const initCategories = () => {
    getCategories().then(data => {
      if (data.error) {
        setValues({ ...values, error: data.error })
      } else {
        setCategories(data)
        setValues({ ...values, loaded: true })
        console.log(categories)
      }
    })
    // getCollect()
  }

  const getCollect = () => {
    if(categories) {
      let mov = []
      categories.map((c, i) => {
        getCollections(c.slug, 6).then(data => {
          if (data.error) {
            console.log(data.error)
          } else {
            mov.push({ name: data.category.name, movies: data.movies })
          }
        })
      })
      setCollections(mov)
    } else {
      console.log('Categories are empty')
    }
  }


  return (
    <>
      <div></div>
    </>
  );
}


export default Collect;
  • Вопрос задан
  • 85 просмотров
Пригласить эксперта
Ответы на вопрос 2
@romant094
Можно сделать так:
const initCategories = async () => {
  try {
    const data = await getCategories()
    const collect = await getCollect(data)
    setCategories(data)
    setValues({ ...values, loaded: true })
  } catch (error) {
    setValues({ ...values, error })
  }
}

const getCollect = async data => {
  return await fetch('https://site.com')
}

Не стал переписывать все в точности, но суть, думаю, понятна.
Ответ написан
@rusrich Автор вопроса
Сделал так.
В итоге все работает как надо, но не могу отрендерить, как буд-то функция showMoviesOfCollections(data.movies) ничего не возвращает.
В консоли данные корректные.

Как можно исправить ситуацию?

import React, { useEffect, useState } from 'react';
import Cardstyle from "../../components/movie/cardstyle";
import { getCategories, getCollections, singleCategory } from "../../actions/category";
import Link from "next/link";

const Collect = ({ router }) => {
  const [ categories, setCategories ] = useState([])
  const [ values, setValues ] = useState({
    error: '',
    success: '',
    loaded: false
  })

  useEffect(() => {
    initCategories()
  }, [])

  const initCategories = () => {
    return getCategories().then(data => {
      if (data.error) {
        setValues({ ...values, error: data.error })
      } else {
        setCategories(data)
      }
    })
  }

  const getCollect = (slug, limit) => {
    getCollections(slug, limit).then(data => {
      if (data.error) {
        console.log(data.error)
      } else {
        console.log(data.movies)
        return showMoviesOfCollections(data.movies)
      }
    })
  }

  const showMoviesOfCollections = (movies) => {
    return movies.map((movie, i) => {
      return (
        <div key={ i } className="col-6 col-sm-6 col-md-4 col-xl-2 mt-5 mb-5 mb-xl-0">
          <Cardstyle movie={ movie }/>
        </div>
      )
    })
  }

  const viewCollection = () => {
    return categories.map((cat, i) => {
      return (
        <div key={ i } className="bg-gray-1100 dark">
          { getCollect(cat.slug, 6) }
        </div>
      )
    })
  }

  return (
    <>
      { viewCollection() }
    </>
  );
}


export default Collect;
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы