1

I'm trying to learn react and I'm creating a web app with firebase database and auth and the movie db api. I'm able to have a user click on a movie and add that movie to their watchlist "sends info of that movie to firebase". now I'm trying to retrieve that info, and I'm successful in doing so, but my code currently causes the browser to lock up and crashes and keeps logging endlessly and I need to force quit. I'm not sure where I'm going wrong? When I put the code that's in the render in the constructor, or in a componentDidMount, this.props.user returns null. I'm confused :(

app.js constructor

passing state to watchlist component

heres the code:

import React, { Component } from 'react'
import firebase from '../config/Firebase';

import { Container } from 'react-bootstrap';

import WatchlistMovie from './WatchlistMovie';

export default class Watchlist extends Component {
  constructor(props){
    super(props);
    this.state = {
      movies: [],
    }
  }

  render() {

    const movieRef = firebase.database().ref(`watchlist/${this.props.user}`);

    movieRef.on("value", snapshot => {
      let movies = snapshot.val();

      console.log(movies);

      let newState = [];

      for(let movie in movies){
        newState.push({
          id: movies[movie].id,
          title: movies[movie].title,
          rating: movies[movie].rating,
          poster: movies[movie].poster
        });
      }

      this.setState({
        movies: newState
      });

      console.log(this.state.movies);

    });


    return (
      <div>
        <Container>
            <WatchlistMovie
              ... send data from firebase to this individual movie component
            />
        </Container>
      </div>
    )
  }
}
14
  • Can you post the error trace? Commented Mar 13, 2019 at 4:05
  • no error in terminal, console just keeps logging (this.state.movies) causing browser to crash Commented Mar 13, 2019 at 4:16
  • 2
    Hi, You can't call setState inside render function as changing the state re-renders the component so you get a infinite loop where your render function calls setState and because of setState your render functions gets called again. You need to take this code and put it in componentDidMount lifecycle function Commented Mar 13, 2019 at 4:18
  • Hey Rishabh, when i put it in a componentDidMount lifecycle, this.props.user is recieved as null Commented Mar 13, 2019 at 4:20
  • Can you show where the props are being passed? Commented Mar 13, 2019 at 4:25

1 Answer 1

1

render() {...} is not the place to fetch data. Move it to componentDidMount as below:


export default class Watchlist extends Component {
  constructor(props){
    super(props);
    this.state = {
      movies: [],
    }
  }

  componentDidMount() {
    const movieRef = firebase.database().ref(`watchlist/${this.props.user}`);

    movieRef.on("value", snapshot => {

      // I keep your logic here
      let movies = snapshot.val();

      console.log(movies);

      let newState = [];

      for(let movie in movies){
        newState.push({
          id: movies[movie].id,
          title: movies[movie].title,
          rating: movies[movie].rating,
          poster: movies[movie].poster
        });
      }

      this.setState({
        movies: newState
      });



    });
  }

  render() {

    const { movies } = this.state;


    return (
      <div>
        <Container>
            <WatchlistMovie
              ... send data from firebase to this individual movie component
            />
        </Container>
      </div>
    )
  }
}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.