iT邦幫忙

2

React 的事件處理與四種方法 (下)

挑戰 React 第十六篇

上篇講解找不到綁定的this,因此 setState 才會 undefined,此篇會講解如何解決上述狀況的四種方式。

目標

按了按鈕,訊息改變

第一種方式

render method裡 event 事件方法綁定 this

handleClickMessage() {
    console.log(this);
    this.setState({
      message: '訊息已改變'
    })
  }

render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button onClick={this.handleClickMessage.bind(this)}>click</button>
      </div>
    )
  }
  1. 找到此組件綁定的 this,因此可以呼叫 this.setState
  2. 確認按了按鈕,訊息改變

第二種方式

與第一種方式一樣,只是改用 arrow function,因此可以看到 handleClickMessage 有 + 小括弧

 render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button onClick={() => this.handleClickMessage()}>click</button>
      </div>
    )
  }

第三種方式

與第一種方式雷同,但綁定的方法改放在 constructor,最後結論會在說明差別在哪裡。

import React, { Component } from 'react'

class EventBind extends Component {
  constructor(props) {
    super(props)
  
    this.state = {
       message: '初始訊息'
    }
    // 在 constructor 綁定事件方法
    this.handleClickMessage = this.handleClickMessage.bind(this);
  }
  
  handleClickMessage() {
    console.log(this);
    this.setState({
      message: '訊息已改變'
    })
  }

  render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button onClick={this.handleClickMessage}>click</button>
      </div>
    )
  }
}

export default EventBind

第四種方式

事件處理的方法直接使用 arrow function

import React, { Component } from 'react'

class EventBind extends Component {
  constructor(props) {
    super(props)
  
    this.state = {
       message: '初始訊息'
    }
  }
  
  // 方法直接使用 arrow function
  handleClickMessage = () => {
    console.log(this);
    this.setState({
      message: '訊息已改變'
    })
  }

  render() {
    return (
      <div>
        <div>{this.state.message}</div>
        <button onClick={this.handleClickMessage}>click</button>
      </div>
    )
  }
}

export default EventBind

結論

  • 第一種與第二種方法都放在 render 裡面,若有需要 rerender 重新渲染 的情況,可能會有效能上的問題。
  • 但第一種與第二種方式可以有彈性的將參數傳給 Event Handler。以下舉例為傳送參數 id:
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
  • 第三種與第四種是我們組內常會使用的方式,因為放在 constructor 所以只會呼叫一次,不像第一二種可能在較複雜的情況會有效能的問題。

我還在學習的階段,若有寫錯的訊息,都可以直接留言告知感謝!!!


2 則留言

0

這篇講得很詳細,還提出效能問題,學習了 ヽ( ´ ▽ ` )ノ

很開心你這樣說,感覺又有動力寫下去/images/emoticon/emoticon37.gif

0
harry xie
iT邦新手 4 級 ‧ 2019-12-19 10:38:54

目前學習 React 的進度跟你差不多,一起加油吧!!/images/emoticon/emoticon07.gif

Fighting~~~

我要留言

立即登入留言