从Firebase异步获取数据

时间:2020-02-17 10:36:28

标签: reactjs firebase google-cloud-firestore async-await

我正在尝试从Firebase集合中获取一些数据,但是我似乎无法使其正常工作。

我的代码如下:-

组件:-

import React, { Component } from 'react'
import { connect } from 'react-redux';
import { fetchPlayers } from '../../redux/players/players.actions';

class Players extends Component {

    componentDidMount() {
        this.props.fetchPlayers(); 
    }

    render() {
        const { players } = this.props;

        // const playerItems = players.map(player => (
        //     <div key={player.id}>
        //         <h3>{player.name}</h3>
        //     </div>
        // ));

        return (
            <div>
                <h1>PLAYERS</h1>
                {/* {playerItems} */}
            </div>
        )
    }
}

const mapStateToProps = state => ({
    players: state.players.items,
    newPlayer: state.players.item
});

export default connect(mapStateToProps, {fetchPlayers})(Players);

我的动作文件如下所示:-

import { FETCH_PLAYERS, NEW_PLAYER } from "./players.types";
import { getPlayers, addPlayer } from '../../db/firebase/players.firebase';

// this syntax below will return the dispatch (to the reducer)
export const fetchPlayers = () => dispatch => {
  const players = getPlayers();
  dispatch({
    type: FETCH_PLAYERS,
    payload: players
  });
};

export const createPlayer = playerToAdd => dispatch => {
    addPlayer(playerToAdd);
    dispatch({
        type: NEW_PLAYER,
        payload: playerToAdd
  });
};

我的数据库函数如下:-

import firebase from "../../config/firebase";

const db = firebase.firestore();

export const getPlayers = () => {
    const players = fetchData();
    return players;
}

export const addPlayer = (playerToAdd) => {
    db.collection("players").add({ ...playerToAdd });
}

const fetchData = async () => {
    let playerArr = [];
    await db.collection("players")
    .get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            playerArr = playerArr.concat(doc.data());
        });
    })
    .catch(function(error) {
        console.log("Error getting documents: ", error);
    });

    return playerArr;

}

我的问题是,在我的组件中,播放器仍然是一个诺言,之后将返回fetchData()db调用。

如何等待数组首先填充(在fetchData()中),然后通过操作将其传递给组件?

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我设法以这种方式修复它,虽然不确定这是否是正确的方法,但是对于Redux还是很新的:-

组件:-

import React, { Component } from 'react'
import { connect } from 'react-redux';
import { fetchPlayers } from '../../redux/players/players.actions';

class Players extends Component {

    componentDidMount() {
        this.props.fetchPlayers(); 
    }

    render() {

        const {players} = this.props;
        let playerItems = ''

        if (players) {
            playerItems = players.map(player => (
                <div key={player.id}>
                    <h3>{player.name}</h3>
                </div>
            ));
        }


        return (
            <div>
                <h1>PLAYERS</h1>
                    {playerItems}
            </div>
        )
    }
}

const mapStateToProps = state => ({
    players: state.players.items,
    newPlayer: state.players.item
});

导出默认的connect(mapStateToProps,{fetchPlayers})(播放器);

动作:-

import { FETCH_PLAYERS, NEW_PLAYER } from "./players.types";
import { getPlayers, addPlayer } from '../../db/firebase/players.firebase';

// this syntax below will return the dispatch (to the reducer)
export const fetchPlayers = () => async dispatch => {
  const players = await getPlayers();
  dispatch({
    type: FETCH_PLAYERS,
    payload: players
  });
};

export const createPlayer = playerToAdd => dispatch => {
    addPlayer(playerToAdd);
    dispatch({
        type: NEW_PLAYER,
        payload: playerToAdd
  });
};

firebase:-

import firebase from "../../config/firebase";

const db = firebase.firestore();

export const getPlayers = async () => {
    const players = await fetchData();
    return players;
}

export const addPlayer = (playerToAdd) => {
    db.collection("players").add({ ...playerToAdd });
}

const fetchData = async () => {
    let playerArr = [];
    await db.collection("players")
    .get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            playerArr = playerArr.concat(doc.data());
        });
    })
    .catch(function(error) {
        console.log("Error getting documents: ", error);
    });

    return playerArr;

}

通过这种方式,如果您有任何建议,欢迎您多听听。

谢谢