realph
realph

Reputation: 4671

React: Pass Firebase Data Down Via Props

I'm trying to pass some Firebase data down from one component via props to another component, but it doesn't seem to be letting me iterate over the Firebase data in the child component.

App.js

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      games: []
    };
  }

  componentDidMount() {
    const gamesRef = firebase.database().ref('games').orderByKey();

    gamesRef.once('value', snap => {
      snap.forEach((childSnapshot) => {
        this.state.games.push(childSnapshot.val());
      })
    })
  }

  render() {
    return (
      <div className="App">
        <Games data={ this.state.games } />
      </div>
    );
  }
}

Games.js

class Games extends Component {
  componentDidMount() {
    console.log(this.props.data); // this logs successfully  
  }

  render() {
    return (
      <div className="container">
        <div className="Games flex flex-end flex-wrap">
          { this.props.data.map(function (game, i) {            
            return (
              <h1>{ game.title }</h1>
            )
          }) }
        </div>

      </div>
    );
  }
}

For some reason I'm having a problem when trying to map() over my props.data. It's definitely being passed down to my Games component, because it's printing the console.log(this.props.data) to the console with the data it gets back from Firebase.

Do I have to wait for my Firebase data to resolve before mapping over it, and if so how do I do this?

Any help is appreciated. Thanks in advance!

Upvotes: 2

Views: 2261

Answers (1)

Ben Hare
Ben Hare

Reputation: 4415

I think the problem lies with your componentDidMount in your App class. You're updating state with

this.state.games.push(childSnapshot.val());

You shouldn't do that. State should only be updated with this.setState (or at the very least you should use this.forceUpdate()), as otherwise it will not re-render. I would instead advise doing

componentDidMount() {
  const gamesRef = firebase.database().ref('games').orderByKey();
  let newGames;

  gamesRef.once('value', snap => {
    snap.forEach((childSnapshot) => {
      newGames.push(childSnapshot.val());
    })
  })

  this.setState({games: newGames});
}

This will cause a re-render of the App component, causing the new data to be passed as a prop to the Games component.

Upvotes: 1

Related Questions