我正在通过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完成以上操作。另外,我认为projects.map()
中的return语句不起作用。我尝试了Promise和Async Await,但是不确定如何构造它。
答案 0 :(得分:2)
类似于类组件,您将需要使用功能组件中的useState钩子来定义state
。
此外,您应该使用useEffect
钩子来处理HTTP请求的执行,以使它不会在每次重新渲染时都被触发。我们添加了一个空数组([]
)作为useEffect
钩子的第二个参数,以使其仅运行一次,如官方的React钩子documentation所述。
返回响应后,我们通过调用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)