簡體   English   中英

React map function 組件渲染時不執行

[英]React map function does not execute when the component is rendered

正如您在下面的開發工具屏幕截圖中看到的那樣,子元素確實有道具。 我的問題是,當組件首次呈現時,我無法讓它們出現在 DOM 中。 我必須再次單擊鏈接元素以重新渲染組件,然后 map function 才能正常工作(第二個屏幕截圖)。 另一件事是我在另一個組件中使用相同的代碼,它工作正常。 幫助!

import React, { useState, useEffect } from 'react'
import firebase from 'firebase';
import NewsLetterListChildComponent from './children/NewsLetterListChildComponent';
import LoadingComponent from '../Loading/LoadingComponent';

function PublicNewsLetterListComponent({ user }) {
    const [ newsLetters, setNewsLetters ] = useState([]);
    const [ loading, setLoading ] = useState(false);
    const [ errors, setErrors ] = useState(false);

    useEffect(() => {
        let requestCancelled = false;

        const getNewsLetters = () => {
            setLoading(true);
            let newsLetterArray = [];
            firebase
                    .firestore()
                    .collection('newsLetters')
                    .get()
                    .then((querySnapshot) => {
                        querySnapshot.forEach((doc) => {
                        const listRef = firebase.storage().ref().child('newsLetterImagesRef/' + doc.id);
                        listRef
                            .getDownloadURL()
                            .then(url => {
                                newsLetterArray.push({ id: doc.id, data: doc.data(), image: url });
                            })
                            .catch(error => console.log(error))
                });
            });

            setNewsLetters(newsLetterArray);
            setLoading(false);
        };

        getNewsLetters();

         return () => {
            requestCancelled = true;
         };
    }, []);
    
    const renderContent = () => {
        if(loading) {
            return <LoadingComponent />
        } else {
            return <NewsLetterListChildComponent newsLetters={newsLetters} /> 
        }
    }
    return renderContent();

    
}

export default PublicNewsLetterListComponent
import React from 'react';
import { ListGroup, ListGroupItem, Row, Col } from 'reactstrap';

function NewsLetterListChildComponent({ newsLetters }) {
    return (
    <div>
        <Row>
            <Col md={{size: 6, offset: 3}}>
                <ListGroup>
                {newsLetters.map((item, index) => {
                    return (
                        <ListGroupItem key={index} className="m-1" ><h1>{item.data.title} </h1><img src={item.image} alt={item.data.title} className="thumb-size img-thumbnail float-right" /></ListGroupItem>
                    );
                })}
                </ListGroup>
            </Col>
        </Row>
    </div>
    )
}

export default NewsLetterListChildComponent;

初始渲染和列表組為空

初始渲染和列表組為空

重新渲染后,現在列表組已填充

重新渲染后,現在列表組已填充

解析數據后,您需要調用setNewsLetters

const getNewsLetters = async () => {
  setLoading(true);
  
  try {
    const newsLetters = await firebase
      .firestore()
      .collection("newsLetters")
      .get();
  
    const data = await Promise.all(
      newsLetters.docs.map(async (doc) => {
        const url = await firebase
          .storage()
          .ref()
          .child("newsLetterImagesRef/" + doc.id)
          .getDownloadURL();

        return {
          id: doc.id,
          data: doc.data(),
          image: url,
        };
      })
    );
    
    setNewsLetters(data);
  } catch (error) {
    console.log(error);
  } finally {
    setLoading(false);
  }
};

useEffect 代碼包含一個異步請求,並且您正在嘗試更新 state 中的 newsLetters 數組,甚至在它被獲取之前。 利用 Promise.all 並在可用時更新數據

useEffect(() => {
    let requestCancelled = false;

    const getNewsLetters = () => {
        setLoading(true);
        firebase
                .firestore()
                .collection('newsLetters')
                .get()
                .then((querySnapshot) => {
                    const promises = querySnapshot.map((doc) => {
                    const listRef = firebase.storage().ref().child('newsLetterImagesRef/' + doc.id);
                    return listRef
                        .getDownloadURL()
                        .then(url => {
                            return { id: doc.id, data: doc.data(), image: url };
                        })
                        .catch(error => console.log(error))
                    Promise.all(promises).then(newsLetterArray => { setNewsLetters(newsLetterArray);})
            });
        });

        
        setLoading(false);
    };

    getNewsLetters();

     return () => {
        requestCancelled = true;
     };
}, []);

如果您使用 if 檢查newletters,您的問題很可能會得到解決。

查看詳細信息: https://www.debuggr.io/react-map-of-undefined/

 if (newLetters){ newLetters.map(item=>...) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM