【问题标题】:Can not setState on Websocket.onmessage无法在 Websocket.onmessage 上设置状态
【发布时间】:2021-02-23 17:49:38
【问题描述】:

我正在尝试为我的应用实现聊天页面。

我正在使用 react 和 django 频道。 我在 Websocket.onmessage 上呈现消息时遇到问题 这是给我错误的代码

// ask for the user
const request = new XMLHttpRequest()
const csrftoken = Cookies.get('csrftoken');
request.open('POST', "/get_user", true)
request.setRequestHeader("X-CSRFToken", csrftoken);
request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
request.onload = function () {
  const user = JSON.parse(request.responseText).user
  const room_name = 'lobby'
  // channels stuff
  const chatSocket = new WebSocket(
    'ws://' + window.location.host +
    '/ws/chat/' + room_name + '/');

  chatSocket.onclose = function(e) {
    console.error("Socket closed unexpectedly.", e)
  }


  function Convo_bubble(props){
    if (props.user !== 'Customer Support'){

      return(
        <div className='bubble_container'>
          <p className='bubble_info'> {props.user} </p>
          <div className='bubble'>{props.message}</div>
        </div>
      )

    }
    else {

      return (
        <div className='bubble_container_admin'>
          <p className='bubble_info'> {props.user} </p>
          <div className='bubble_admin'>{props.message}</div>
        </div>
      )

    }
  }


  class Chat_app extends React.Component {
    constructor(props) {
      super(props)
      this.state = {
        messages: [{message: 'Hi, how can I help you today?', user:'Customer Support'}],
      }

    }

    addMessage(){
      chatSocket.onmessage = function(e) {
        const data = JSON.parse(e.data);
        const sender = data['sender']
        var message = data['message']
        console.log(data)
        if (message !== ''){
          
          this.setState({
            messages: [...this.state.messages, {message: message, user: user}],
          })
          document.getElementById('message_input').value = ''
          }
      }
      const text = document.getElementById('message_input').value
        if (text !== ''){
          chatSocket.send(JSON.stringify({
              'message': text,
              'user': user,
          }));
        }
      }

    checkEnter(e) {
      if (e.key === 'Enter'){
        this.addMessage()
      }
    }

    componentDidUpdate() {
      document.getElementById('scrollto').scrollIntoView()
    }
    render () {

      return (
        <div>
          <h1>Questions? A customer reppresentative will be happy to assist you</h1>
          <div className="chat_container">
            <div className="conversation_container">
              {this.state.messages.map(message => <div><Convo_bubble
              message={message.message} user={message.user} /><br /> </div>)
            }
            <div id='scrollto'></div>
            </div>
            <div className="Compose_message_container">
              <input  onKeyPress={() => this.checkEnter(event)} id='message_input' type='text' placeholder="Type your message here..."/>
              <button id="submit_message_button" onClick={() => this.addMessage()}><i className="fa fa-send"></i></button>

            </div>
          </div>
        </div>
      )
    }
  }


  ReactDOM.render(
    <Chat_app />, document.querySelector("#root")
  )
  // focus on the input bar
  document.querySelector("#message_input").focus()


}
request.send()

这是控制台中的错误消息:Uncaught TypeError: Cannot read property 'messages' of undefined

错误是由 this.setState({....})引起的 有什么想法我错了吗?

【问题讨论】:

  • 你初始化你的状态了吗? this.state.messages = []
  • 让我添加整个代码
  • 添加了代码!

标签: reactjs websocket django-channels


【解决方案1】:

您需要在构造函数中使用“this”参数绑定 addMessage 函数。因此,您的函数具有类的上下文。

constructor(props) {
  super(props)
  this.state = {
    messages: [{message: 'Hi, how can I help you today?', user:'Customer Support'}],
  }
  this.addMessage = this.addMessage.bind(this);
}

并将函数更改为胖箭头以自动绑定上下文

 chatSocket.onmessage = (e) => {…}

【讨论】:

  • 天哪,它成功了,非常感谢你......我能问你为什么吗?为什么箭头符号有效?
  • 因为同理,函数不会绑定上下文,所以需要手动绑定。但是箭头符号会自动绑定。不客气
猜你喜欢
  • 2022-08-09
  • 2020-08-26
  • 2017-03-05
  • 2018-10-02
  • 2020-08-26
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多