0

I am creating a table that is populated with data after pulling the data. The issue is that on the first render the data is duplicated and the tables rows therefore have duplicates as well but when the page is reloaded, the data is no longer duplicated. Why is my data duplicating itself on the first load but not on the loads after?

Here is my code:

import React from 'react';
import { firebaseAuth } from './../config/constants'
import firebase from 'firebase'

class PeopleDash extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      uid: '',
      people: [],
      peopleTableArray: [["name", "dateOfBirth", "height", "doneWithSchool"]]
    };
  }

  componentWillMount() {
    this.setState({ people: [] });
  }

  componentDidMount() {
    firebase.auth().onAuthStateChanged(function (user) {
      if (user) {
        console.log(user.uid);
        this.setState({ uid: user.uid });
        this.setState({ people: [] });
        var firebaseChild = this.props.firebaseChild;
        const ref = firebase.database().ref().child(firebaseChild).child(user.uid);
        ref.once("value", function(snapshot){
          snapshot.forEach(function(data){
            this.setState({
              people: this.state.people.concat(data.val())
            })
            console.log(this.state.people);  //ISSUE

//ISSUE: at this point you can see the console log duplicates on the first page load but not any load after that

          }.bind(this));
        }.bind(this));
      } else {
        console.log("no data");
      }
    }.bind(this));
    console.log('componentDidMount ended and this.state.people = ' + {this.state.people});
  }

  render() {
    return (
      <div className="contentRow" id={this.props.id}>
        <div className="dynamicSnapshotTable">
        {
          // loop through each snapshot on firebase (for the user logged in)
          this.state.people.map((item, i) => {

            return (
              <div key={i} id={item.name} className="tableRowDiv">
              {
                this.props.tableArray.map((attribute, j) => {
                  return (
                    <div key={j} className="tableDataDiv">
                      {(this.props.tableArray[j] == 'doneWithSchool') ? (
                        (item[this.props.tableArray[j]]) ? ('tru') : ('fal')
                      ) : (
                        item[this.props.tableArray[j]]
                      )}
                    </div>
                  );
                })
              }

              </div>
            );
          })
        }
        </div>
      </div>
    );
  }
}

PeopleDash.propsTypes = {
  id: React.PropTypes.string,
  tableArray: React.PropTypes.array,
  firebaseChild: React.PropTypes.string,
};


export default PeopleDash;

Thank you in advance!

1 Answer 1

1

The onAuthStateChanged event may fire multiple times. Each time it does, you're adding more people to the display.

To solve this, make sure you just use the people from the query:

ref.once("value", function(snapshot){
    var people = [];
    snapshot.forEach(function(data){
        people.push(data.val());
    });
    this.setState({
        people: people
    })

This also ensure that you call setState() only once (for each time the auth state changes), which will improve performance a bit.

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.