ymho
ymho

Reputation: 41

React Native component not getting updated when firebase realtime database listener returns a new value

I am new to react and I am building my final year project using it. I am currently trying to display the game times, however when I add a new game or update a game time the component is not getting re-rendered without me manually refreshing the page. My code is below:

import React from "react";
import { Button, StyleSheet, Text, TextInput, View, ScrollView } from "react-native";
import * as firebase from 'firebase';



class AdvancedSearchScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      games: []
    }
    this.props.watchUserData();
    var database = firebase.database();
    var commentsRef = firebase.database().ref('games');
    commentsRef.on('child_added', (data) => {
      this.state.games.push(data.val());
    });

    commentsRef.on('child_changed', (data) => {
      this.state.games.push(data.val());
    });
  }
  render() {  
    return(
    <ScrollView>
    <View style={styles.container}> 
      {this.state.games.map(type => <Text>{type.gameTime}</Text>)}
    </View>
    </ScrollView>
    );
  }
}

export default AdvancedSearchScreen;

Upvotes: 0

Views: 64

Answers (1)

Lu&#237;s C Meireles
Lu&#237;s C Meireles

Reputation: 469

In this case I think you should move you state update to a componentDidMount() using the this.state.games.push(data.val()); will not trigger a new render, you need to use the setState() function, something like this should work for you:

class AdvancedSearchScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      games: []
    }
  }
  
  componentDidMount() {
    this.props.watchUserData();
    var database = firebase.database();
    var commentsRef = firebase.database().ref('games');
    commentsRef.on('child_added', (data) => {
      const newItem = data.val()
      this.setState({games: [...this.state.games, newItem]})
    });

    commentsRef.on('child_changed', (data) => {
      const newItem = data.val()
      this.setState({games: [...this.state.games, newItem]})
    });
  }

  render() {
    return(
      <ScrollView>
        <View style={styles.container}>
          {this.state.games.map(type => <Text>{type.gameTime}</Text>)}
        </View>
      </ScrollView>
    );
  }
}

export default AdvancedSearchScreen;

something like this should force the render.

Upvotes: 1

Related Questions