Arte2
Arte2

Reputation: 333

State is defined in "ComponentDidMount" but undefined in render

I extract data from my "ComponentDidMount" function and load them in my state. Straight after I console log the value and see everything is there. However, when I try to access the state the same way in my return in my render function, I will get "undefined".

public componentDidMount() {
sp.web.lists.getByTitle("alert").items.get().then((item) => {
  this.setState({items: item})
  console.log(this.state.items[0].Title) //works
})

}

Above console log "(this.state.items[0].Title)" works. I try to use the state the same way in my render function:

 <span className={ styles.title }>{this.state.items[0].Title}</span>

Does not work, and the value is undefined. How come? I store the data in my state when the component is loaded, and expected the data to be there when I refered to state in my render. How come?

Upvotes: 1

Views: 200

Answers (1)

Yousaf
Yousaf

Reputation: 29282

componentDidMount is called after the initial render of the component. So when render function is called for the first time, this.state.items[0].Title would be undefined.

Once the component has rendered, then componentDidMount will execute and update the state and re-render your component.

Inside the render function, access Title property only if this.state.items[0] is defined.

<span className={ styles.title }>
   { this.state.items[0] && this.state.items[0].Title }
</span>

One more thing that you should be aware of is that this.setState function updates the state asynchronously, so trying to log the state immediately after this.setState function call will give you the previous value of state.

If you want to log the latest state, you could pass an optional second argument to this.setState function. This second argument is a callback function which is called after state has been updated.

this.setState({items: item}, () => {
    console.log(this.state.items[0].Title)
})

Upvotes: 3

Related Questions