0

I have this block of code

class PaintingPage extends Component {
 constructor(props){
   super(props)
   this.state = {
     paintings: []
   }
   this.database = this.database.bind(this);
 }

 database = () => {
   let db = fire.firestore();
   db.collection('PaintingProjects')
   .get()
   .then( snapshot => {
     let paintingData = [];
     snapshot.forEach( doc => {
       const data = doc.data()
       paintingData.push(data);
       console.log(paintingData, '1st')
       this.setState({
         paintings: paintingData,
       })
       console.log(this.paintings, '2nd')
     })
   })
 }

 componentWillMount(){
   this.database()
 }

I'm trying to save my PaintingProjects collection to my state. When I log the paintingData array all of my data is there but after I save it to my state and log my state its comes back as undefinied what am I doing wrong?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Cristof.M
  • 25
  • 7
  • `setState()` is an asynchronous operation. See https://stackoverflow.com/questions/36085726/why-is-setstate-in-reactjs-async-instead-of-sync – Frank van Puffelen Jul 07 '20 at 22:41

2 Answers2

0

Use componentDidMount instead of willMount.

"componentWillMount() is invoked immediately before mounting occurs. It is called before render() , therefore setting state in this method will not trigger a re-render. Avoid introducing any side-effects or subscriptions in this method"

Mr. Robot
  • 1,334
  • 6
  • 27
  • 79
0

console.log(this.paintings, '2nd') won't log the new state, but undefined, you should use this.state.paintings, but mind that it will log the previous state and not the new one.

You also shouldn't introduce side effects in componentWillMount. ComponentWillMount isn't awaited so your component will render without data at least once the same happens with componentDidMount though. But with componentDidMount, you can ensure that your componenet has support for an empty state.

Sources:

Arthur Bruel
  • 678
  • 3
  • 12
  • `this.paintings` will always be undefined since it's, well, not defined. You must access the property inside of the state: `this.state.paintings`. That being said, it's definitely the old state when logged after a `setState` call since, like the duplicate points out, it's async. – Emile Bergeron Jul 07 '20 at 22:47
  • True, I missed that. Been using function components for a few months now. Thanks. – Arthur Bruel Jul 07 '20 at 23:12