简体   繁体   中英

How to call a function to change the state within a callback function?

I am implementing a Welcome Display web app that takes a guest name received from RabbitMQ and populates it on the screen. In the callback function of the stompClient.subscribe(... I want to call the function to change the state of the reservation and view on the screen. When I call the function it says the function is not defined. How can I change the state every time I receive the message?

import React from 'react';
import '../css/App.css'
import WelcomeVisitor from '../pages/WelcomeVisitor';
import ThankYou from '../pages/ThankYou';
import Stomp from 'stompjs'



class App extends React.Component {

  constructor(props){
    super(props)
    this.state = {
      currentView: 'ThankYou',
      currentReservation: null
    }

    this.siteId = props.match.params.siteId
    this.bayNumber = props.match.params.bayNumber
    this.changeView = this.changeView.bind(this)
    this.connectRabbit = this.connectRabbit.bind(this)
  }

  changeView(view){
    this.setState({
      currentView: view
    })
  }

 changeReservation(reservation){
    this.setState({
      currentReservation: reservation
    })
  }

  render(){

    let view = ''  

    this.connectRabbit(this.siteId, this.bayNumber)

    if(this.state.currentView === 'ThankYou'){
      view = <ThankYou changeView={this.changeView}/>
    } else if(this.state.currentView === 'WelcomeVisitor') {
      view = <WelcomeVisitor guestName='Quinton Thompson'/>
    } 


      return (
        <div className="App">
          {view}
        </div>
        )

    }


    connectRabbit(siteId, bayNumber){

      let stompClient

          var ws = new WebSocket('ws://localhost:15674/ws')

          const connectHeaders = {
              'login': 'guest',
              'passcode': 'guest',
          }

          const queueHeaders = {
              'x-queue-name': `${bayNumber}.visit.out.display`,
              'durable': 'true',
              'auto-delete': 'false'
          }
          stompClient = Stomp.over(ws)

          stompClient.connect(connectHeaders , function(frame){
                      console.log('Connected')
                     stompClient.subscribe('/exchange/ds.game/visit.out',function(message){
                       //changeReservation and changeView is not defined
                         this.changeReservation(message.body)
                         this.changeView('WelcomeVisitor')
                     }, queueHeaders)
                     console.log('here')
          })
      }


}

export default App;

The this object in your function callback is likely not referencing the this object in your class.

Changing the function syntax to: (message) => {} and (frame) => {} should make it work. See below:

stompClient.connect(connectHeaders ,(frame) => {
                      console.log('Connected')
                     stompClient.subscribe('/exchange/ds.game/visit.out', (message) => {
                       //changeReservation and changeView is not defined
                         this.changeReservation(message.body)
                         this.changeView('WelcomeVisitor')
                     }, queueHeaders)
                     console.log('here')
          })

While the code snippet above would make your code work, ideally we should avoid writing these types of callback initializations on the fly ( in render method ), maybe better way of doing it would be creating function calls and referencing those as callbacks. Something like this ( more improvements can be made but just as an example ) :

connectCallback(stompClient, queueHeaders, frame) {
    console.log('Connected');
    stompClient.subscribe('/exchange/ds.game/visit.out', (message) => { 
        this.subscribeCallback(message)
    }, queueHeaders);
}

subscribeCallback(message) {
    this.changeReservation(message.body)
    this.changeView('WelcomeVisitor')
}

Then just use the two functions above as a callback in your render code.

Lastly, you might need to bind changeReservation(reservation) also before anything else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM