首页 > 解决方案 > ReactJs 仅通过映射一组 URL 来渲染一个 img 元素

问题描述

我正在从 firebase 存储读取图像数据并获取数组中图像的 URL。我控制台记录了阵列。没事。

我通过该数组上的函数创建了一个img元素变量。map()

这个变量也很好。

但我无法在组件中渲染多个。只有最后一个图像标签从数组中呈现。

import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'


function Dashboard() {

    const [error, setError] = useState('')
    const { currentUser, logout } = UseAuth()
    const history = useHistory()
    const picURLS = []
    const [photo, setPhoto] = useState()

    async function getPics() {
        const DBRef = db.collection('pics');
        const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
        if (snapshot.empty) {
            console.log('No matching documents.');
            return;
        }

        snapshot.forEach(doc => {
            var storage = app.storage();
            var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
            gsReference.getDownloadURL().then(function (url) {
                picURLS.push(url);

            }).catch(function (error) {
                console.log(error)
            });
        });
    }

    useEffect(() => {
        getPics()
        console.log('getPIcs() triggered.')
        console.log(picURLS)
        setPhoto(picURLS.map(postdata => (
            <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />)))
        console.log(photo)
       

    }, [])



    return (
        <div>
            <div>{photo}</div>
            <div className="menu pmd-floating-action" role="navigation">
                <Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
                    <span className="pmd-floating-hidden">Primary</span>
                    <i className="material-icons pmd-sm">add</i>
                </Link>
            </div>
        </div>


    )
}

export default Dashboard

标签: reactjsfirebase

解决方案


最好将 picURLS 添加到您的状态变量中,因为 useEffect 仅在依赖项数组为空的情况下运行一次,而 setPhoto(picURLS.map) 在填充之前肯定会与空的 picURLS 数组一起使用。所以你的照片变量肯定是空的。你应该在渲染函数中调用你的地图;

{picURLS.map(postdata => (
            <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}

试试这个代码

import React, { useRef, useState, useEffect } from 'react'
import { Card, Button, Alert } from 'react-bootstrap'
import { Link, useHistory } from 'react-router-dom'
import { UseAuth } from '../context/AuthContex'
import app from './../firebase'
import { db } from './../firebase'
import './Dashboard.css'


function Dashboard() {

    const [error, setError] = useState('')
    const { currentUser, logout } = UseAuth()
    const history = useHistory()
    const [picURLS, setPicURLS] = useState([])

    async function getPics() {
        const DBRef = db.collection('pics');
        const snapshot = await DBRef.where('author', '==', currentUser.uid).get();
        if (snapshot.empty) {
            console.log('No matching documents.');
            return;
        }

        const newUrls = [];
        snapshot.forEach(doc => {
            var storage = app.storage();
            var gsReference = storage.refFromURL('<bucket address>' + doc.data().filename)
            gsReference.getDownloadURL().then(function (url) {
                newUrls.push(url);

            }).catch(function (error) {
                console.log(error)
            });
        });
       setPicURLS(newUrls);
    }

    useEffect(() => {
        getPics()
        console.log('getPIcs() triggered.')
        console.log(picURLS)
    
    }, [])



    return (
        <div>
            <div>{
                   picURLS.map(postdata => (
                     <img className='photoOfOrder' key={postdata} src={postdata} alt={postdata} />))}
            </div>
            <div className="menu pmd-floating-action" role="navigation">
                <Link to='/upload-pic' className="pmd-floating-action-btn btn pmd-btn-fab pmd-btn-raised pmd-ripple-effect btn-primary" data-title="Splash New Image?" href="javascript:void(0);">
                    <span className="pmd-floating-hidden">Primary</span>
                    <i className="material-icons pmd-sm">add</i>
                </Link>
            </div>
        </div>


    )
}

export default Dashboard



推荐阅读