クラス内の関数でthis.state〜プロパティを利用しようとすると、undefinedエラーが出る

`React.Component`をextendsしたclass内にクリックに反応して叩かれる関数を作りました。

その関数の中で`this.state.xxxx`の値を取得しようとすると、undefinedエラーが発生しました。

```javascript
  connect() {
    console.log('connect to the websocket server.')
    ws = new WebSocket('ws://localhost:8080/message')
    ws.onmessage = function(data) {
      const tmpMsgs = this.state.messages
      tmpMsgs.unshift(data.data)
      this.setState({messages: tmpMsgs})
      console.log(data.data)
    }
  }
```

```
Uncaught TypeError: Cannot read property 'messages' of undefined
    at WebSocket.ws.onmessage (MessageForm.js:25)
```

こちらのStackoverflowの記事を参考に`let my = this`を定義し、`this`の代わりに`let my = this`の`my`を利用すればエラーは出なくなったのですが、釈然としません。

https://stackoverflow.com/questions/47704006/how-to-access-this-state-from-a-function-inside-componentdidmount-in-react-nativ

```javascript
  connect() {
    let my = this
    console.log('connect to the websocket server.')
    ws = new WebSocket('ws://localhost:8080/message')
    ws.onmessage = function(data) {
      const tmpMsgs = my.state.messages
      tmpMsgs.unshift(data.data)
      my.setState({messages: tmpMsgs})
      console.log(data.data)
    }
  }
```

以下のReactの解説ページによると、JSX内でのコールバックを利用するときは、クラスメソッドはバインドされていないから注意しなさい、と書かれています。

> You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
[Handling Events](https://reactjs.org/docs/handling-events.html)

上記のページのサンプルにあるように、

```javascript
    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
```

constructorでthisとイベントハンドラを結びつけておく必要がありそうです。
そうすれば、イベントが呼ばれる際に`this`が`undefined`となることはなくなりました。

```javascript
	constructor (props) {
		super(props)
    this.connect = this.connect.bind(this)
```

ニーズがあるかはわかりませんが、作り直したJavaScript全体を貼り直しておきます。

```javascript:MessageForm.js
import React from 'react'

let ws = null
class MessageForm extends React.Component {
	constructor (props) {
		super(props)
    this.connect = this.connect.bind(this)
    this.sendMessage = this.sendMessage.bind(this)
    this.disconnect = this.disconnect.bind(this)

		this.state = {
      ws: null,
      message: '',
      messages: []
    }

	}

	messageChanged (e) {
		this.setState({message: e.target.value})
	}

  componentDidMount() {
    let ws = new WebSocket('ws://localhost:8080/message')
    ws.onmessage = this.handleMessage.bind(this)
    this.setState({ws: ws})
    console.log('websocket is prepared')
  }

  componentWillUnmount() {
    this.state.ws.close()
  }

  //https://gist.github.com/voluntas/14303cbf0a1a5fb47ac58c2682bfa877
  handleMessage(event) {
    let message = event.data
    console.log('handle message ->' + message)
    this.state.messages.push(message)
    this.setState({
      messages: this.state.messages
    })
    console.log('messages -> ' + this.state.messages)
  }

  connect() {
    let ws = new WebSocket('ws://localhost:8080/message')
    ws.onmessage = this.handleMessage.bind(this)
    this.setState({ws: ws})
    console.log('websocket is prepared')
  }

  sendMessage() {
    console.log('send message to websocket server. message -> ' + this.state.message)
    this.state.ws.send(this.state.message)
  }


  disconnect() {
    if (this.state.ws != null) {
      this.state.ws.close()
    }
    console.log('disconnected')
  }


	render() {
		return (
		  <div>
        Connect:
        <button onClick={e => this.connect()}>Connect </button><br />
		    Message: <br/>
		    <input value={this.state.message}
		      onChange={e => this.messageChanged(e)} /><br />
		    <button onClick={e => this.sendMessage()}>Send </button><br />
        disconnect:
        <button onClick={e => this.disconnect()}>Disconnect </button><br />
		  </div>
		)
	}
}

export default MessageForm

```

作り直しの際は以下のGistを参考にさせていただいております。
[React コトハジメ](https://gist.github.com/voluntas/14303cbf0a1a5fb47ac58c2682bfa877)