1

I'm learning react without redux, mobx or any other libraries. The reason why I don't use redux, and so on is that someone told me that it is important to get use to react before using libraries. I'm trying to get data from firestore and render it, but because of async, I'm stuck to render data. I can't render because I don't get data when I render.

My react version is 16 and I practice react with firestore. Here's my code.

I'll appreciate you whatever you give me your advice. Thank you.


CategoryButtonSet.js

import React from 'react';
import CategoryButton from './CategoryButton';
import {test} from '../shared/Firebase';

export default class CategoryButtonSet extends React.Component {
categories = [];

componentDidMount() {
    test().then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            this.categories.push(doc.id).bind(this);
        });
    });
}

render() {
    if(this.categories.length !== 0) {
        console.log(this.categories);
        return (
            <div className="category-block">
                This block is for the category button set.
                {
                    this.categories.map(category => <CategoryButton key={category} name={category}/>)
                }
            </div>
        );
    } else {
        return <div>Loading...</div>;
      }
    }  
}

CategoryButton.js

import React from 'react';

export default (props) => {
    return (
        <div className="category-block__button">
            Here's the category button.
            <button>{props.name}</button>
        </div>
    );
}
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Mingyu Jeon
  • 1,755
  • 5
  • 23
  • 40

2 Answers2

2

You are retrieving data but does not set your state, you don't have any state at all. This is why your component does not re-render after getting data. Maybe one approach could be like this (there could be better ways):

export default class CategoryButtonSet extends React.Component {

    state = {
        categories: [],
    };

componentDidMount() {
    test()
       .then( querySnapshot => querySnapshot.map( doc => doc.id ) )
       .then( data => this.setState( { categories: data } ));
}

render() {
    if(this.state.categories.length) {
        console.log(this.state.categories);
        return (
            <div className="category-block">
                This block is for the category button set.
                {
                    this.state.categories.map(category => <CategoryButton key={category} name={category}/>)
                }
            </div>
        );
    } else {
        return <div>Loading...</div>;
      }
    }  
}
devserkan
  • 16,870
  • 4
  • 31
  • 47
0

Pease have a look at Firestorter, if exists exactly for this purpose and you don't need to create a redux store or anything.

https://github.com/IjzerenHein/firestorter

IjzerenHein
  • 2,690
  • 1
  • 17
  • 13