Подождите, пока массив будет заполнен, а затем визуализировать эти компоненты - PullRequest
0 голосов
/ 13 января 2020

Я получаю список каталогов через хранилище Firebase, а затем, как только он закончится, возвращает список Project компонентов, которые должны быть отображены, каждый с именем, полученным ранее. Как сначала дождаться завершения выборки, а затем вернуть то же количество Project компонентов?

Вот что я пробовал:

import React, {useState} from "react"
import "./index.css"
import {hot} from "react-hot-loader"
import Project from "./Project"
import firebase from "./Firebase.js"

function Projects(props){

    // Get refereance to firebase storage
    let storage = firebase.storage();
    // Reference the main projects folder
    let storageRef = storage.ref().child('projects');
    // Store all project names from firebase storage to then return them as Project components
    let projects = []

    // This lists the directories in 'Projects'
    storageRef.listAll().then(res => {
        // For each directory, push the name into the projects array
        res.prefixes.forEach((folderRef) => {
            projects.push(folderRef.name)
        })
    }).catch(error => {
            console.log(error)
    })

    return(
        <div>
            {projects.map(projName => (
                <>
                    <Project project={projName}/>
                </>

            ))}
        </div>
    )




}

export default hot(module)(Projects)

Однако, когда projects возвращается, он пуст, так как не ждал, пока forEach завершит sh выше. Кроме того, я не думаю, что оператор возврата в projects.map() работает. Я пытался выполнить Promise and Asyn c Await, но я не уверен, как его структурировать.

1 Ответ

2 голосов
/ 13 января 2020

Подобно компонентам класса, вам необходимо определить state, используя хук useState в функциональных компонентах.

Кроме того, вы должны использовать хук useEffect для обработки выполнения HTTP-запроса, чтобы он не запускался при каждом повторном рендеринге. Мы добавили пустой массив ([]) в качестве второго параметра хука useEffect, чтобы он запускался только один раз, как объяснено в официальной документации React документация .

После того, как ответы были возвращены, мы обновляем состояние, вызывая setProjects().

function Projects(props){
  const [ projects, setProjects ] = useState([]);
  let storage = firebase.storage();
  let storageRef = storage.ref().child('projects');

  useEffect(() => {
    const response = []
    storageRef.listAll().then(res => {
    // For each directory, push the name into the projects array
      res.prefixes.forEach((folderRef) => {
        response.push(folderRef.name)
      })
      setProjects(response);
    }).catch(error => {
        console.log(error)
    })
  }, [])

  return(
    <div>
        {projects.length && projects.map((projName, index) => (               
           <Project project={projName} key={index} />
        ))}
    </div>
   )
}

export default hot(module)(Projects)
...