2

I have the following constructor

constructor(props){
    super(props);
    this.renderConversations = this.renderConversations.bind(this);
    this.startConversation = this.startConversation.bind(this);
    this.state = {
      conversationArray: []
    }
} 

In function startConversation I update the state variable.

startConversation(conversationObject) {
    let currentResponse = conversationObject["responses"];
    let thisResponse = currentResponse[Math.floor(Math.random() * currentResponse.length)];

    this.state.conversationArray.push(thisResponse);
    this.renderConversations();

}

In the function renderConversations , I'm doing the following:

renderConversations(){
    let conversationContent = this.state.conversationArray.map((conv, i) => {
      return <View key={i} style={[globalStyle.conversationContainer,globalStyle.shadow]}><Text style= {globalStyle.conversationText}>{ conv }</Text></View>                            
    })
    return conversationContent
}

Finally, in the render function, I render {this.renderConversations()}. Now startConversation is triggered on a button click. But each time I update the state variable the component is not updated, What am I doing wrong?

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
Sooraj
  • 9,717
  • 9
  • 64
  • 99

1 Answers1

3

As per DOC:

Never mutate this.state directly, use setState for that, Treat this.state as if it were immutable.


You are updating the state in a wrong way, "Never mutate the state value directly always use setState to update it". When we use setState react automatically re-render the component with update state value.

Write it like this:

this.setState(prevState => ({
     conversationArray: [...prevState.conversationArray, thisResponse]
}))

Another issue is setState is async, we can not expect the update state value just after the setState, so use callback method of setState and call renderConversations inside that.

Like this:

this.setState(prevState => ({...}), () => this.renderConversations())

Read this answer for more detail about async behaviour of setState.

Suggestion: All the ui logic should be inside render method, so if you want to create ui dynamically call that renderConversations from render.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142