为什么我的数组在React中接收它的函数处为空?

时间:2019-04-22 23:43:55

标签: arrays reactjs mongodb

我将数据从抓取中返回到我的python API。利用数据,我创建了一个新的json字符串数组。如果执行console.log(array),我可以看到该数组包含2个条目。当我将该数组传递给子元素的函数时,该数组为空。我在做什么错了?

这是我的代码。 我对返回数据的python API的调用:

        var myArray = [];
    const baseUrl = 'http://localhost:5000';
    const apiUrl = baseUrl + '/api/load_data';
    fetch(apiUrl, {
        method: 'GET',
        headers: {
            'X-Api-Key': 'react_main',
            'Access-Control-Allow-Origin': 'http://localhost:8080/',
            'Access-Control-Allow-Headers': 'Content-type, Authorization',
            'Accept': 'application/json',
            'Content-type': 'application/json',
        },
    })
        .then(res => res.json())
        .then( res => {
            res.map(function(dataObj) {
                    const data = {
                        id: dataObj['id'],
                        imgLocation: {backgroundImage: dataObj['image']},
                        city: dataObj['city'],
                        state: dataObj['state']
                    }
                    myArray.push(data);
                }
            )

            console.log(myArray);
        });

然后我将其进一步传递给以下功能:

    import PropTypes from "prop-types";
    import React from "react";

    class HomePage extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                cards: [],
            }
        }

        componentDidMount(){
            const baseUrl = 'http://localhost:5000';
            const apiUrl = baseUrl + '/api/load';

            fetch(apiUrl, {
                method: 'GET',
                headers: {
                    'X-Api-Key': 'react_main',
                    'Access-Control-Allow-Origin': 'http://localhost:8080/',
                    'Access-Control-Allow-Headers': 'Content-type, Authorization',
                    'Accept': 'application/json',
                    'Content-type': 'application/json',
                },
            })
                .then(res => res.json())
                .then( res => {
                    res.map(function(cardObj) {
                            const card = {
                                title: cardObj['title'],
                                imgLocation: {backgroundImage: cardObj['image']},
                                city: cardObj['city'],
                                state: cardObj['state'],
                                url: cardObj['url'],
                            }
                            this.setState(prevState => ({cards: [...prevState.cards, card]}))
                        }
                    )
                }).catch((e) => console.log(`Error! ${e.message}`));
        }

        render() {
            var divStyle = {
                clear: 'both',
                display: 'flex',
                justifyContent: 'center'
            };

            return(
                <div>
                    <MainComponents.HeaderElement />
                    <div className="gray-bg-wrapper">
                        <section>
                            <h1 className="section__title">New Cards</h1>
                            <h2 className="section__subtitle">Most recent Cards added</h2>
                            <div className="cards">
                                <MainComponents.CardElement listCards={this.state.cards}
                                />
                            </div>

                            <div style={divStyle}>
                                <a href="/browse/" className="btn btn--cta cards__more-btn">Browse Cards</a>
                            </div>
                        </section>
                    </div>
                    <MainComponents.FooterElement />
                </div>
            )
        }
    }

在MainComponents.CardElement函数中。 listData为空:

    export var CardElement = function(props) {
        return(
            props.listCards.map(function (item) {
                return (
                    <div className="card" key={item.title.replace(' ', '_')}>
                        <div className="exp-card">
                            <a className="nostyle" target="_blank" href={item.url}>
                                <div className="exp-card-image" style={item.imgLocation}>
                                    <div className="card-fader"></div>
                                </div>
                                <div className="exp-card-info">
                                    <div className="exp-card-detail">
                                        <div className="exp-card-title">{item.title}
                                        </div>
                                        <div className="exp-card-location">
                                            <i className="fa fa-map-marker"></i>
                                            <span className="neighborhood">{item.city}, {item.state}</span>
                                        </div>
                                    </div>
                                </div>
                            </a>
                        </div>
                    </div>
                )
            })
        )
    }
    CardElement.propTypes = {
        listCards: PropTypes.array.isRequired,
    }

2 个答案:

答案 0 :(得分:0)

问题出在异步电话上。我以为您会将所有这些代码都放在render()方法中。异步方法(承诺链)将延迟响应。换句话说,渲染将在列表获得值之前执行。要使其工作,您需要将结果移至一个状态并基于此状态进行渲染。基本上,render()方法将被调用两次。最初是空列表,第二次是您的状态更新后。

答案 1 :(得分:0)

我知道了。将我的componentDidMount()函数更改为以下内容使其可以工作。谢谢所有注意到我没有设置状态的人。

    componentDidMount(){
        const baseUrl = 'http://localhost:5000';
        const apiUrl = baseUrl + '/api/load';
        let currentComponent = this;

        fetch(apiUrl, {
            method: 'GET',
            headers: {
                'X-Api-Key': 'react_main',
                'Access-Control-Allow-Origin': 'http://localhost:8080/',
                'Access-Control-Allow-Headers': 'Content-type, Authorization',
                'Accept': 'application/json',
                'Content-type': 'application/json',
            },
        })
            .then(res => res.json())
            .then( res => {
                let arrCards = [];
                res.map(function(cardObj) {
                        const card = {
                            title: cardObj['title'],
                            imgLocation: {backgroundImage: cardObj['image']},
                            url: cardObj['url'],
                            city: cardObj['city'],
                            state: cardObj['state'],
                        }
                        arrCards.push(card);
                        currentComponent.setState(function(){
                            return {
                                cards: arrCards
                            }
                        })
                    }
                )
            }).catch((e) => console.log(`Error! ${e.message}`));
    }