文章

React 中的事件處理

React 中的事件處理

在 React 中,事件處理與 HTML 中的事件處理有一些相似之處,但也有一些關鍵的差異。React 使用合成事件(SyntheticEvent)來處理事件,這是一種跨瀏覽器的包裝,使得事件處理在各個瀏覽器中表現一致。React 中的事件命名方式遵循 JavaScript 標準,而不是 HTML 的小寫方式,並且 React 中的事件處理程序一般寫成函數。

1. 基本事件處理

在 React 中,我們可以在 JSX 中直接附加事件處理程序。與 HTML 不同,React 事件處理程序命名使用駝峰式命名法,並且不使用字串,而是將函數作為處理程序。

範例:簡單的事件處理

1
2
3
4
5
6
7
8
9
10
11
function ClickMeButton() {
  function handleClick() {
    alert('按鈕被點擊了!');
  }

  return (
    <button onClick={handleClick}>
      點擊我
    </button>
  );
}

在這裡,onClick 是 React 中的事件處理器,而 handleClick 是當按鈕被點擊時觸發的函數。

2. 傳遞參數給事件處理程序

有時候,我們希望在事件處理程序中傳遞參數。可以通過箭頭函數或 bind 方法來傳遞參數給事件處理函數。

範例:使用箭頭函數傳遞參數

1
2
3
4
5
6
7
8
9
10
11
function ClickMeButton() {
  function handleClick(message) {
    alert(message);
  }

  return (
    <button onClick={() => handleClick('按鈕被點擊了!')}>
      點擊我
    </button>
  );
}

在這裡,我們使用箭頭函數來傳遞一個參數給 handleClick,這樣當按鈕被點擊時會顯示特定的訊息。

3. 事件對象(Event Object)

React 的事件處理程序會接收一個合成事件物件(SyntheticEvent),這個物件類似於瀏覽器原生事件對象,並且可以在各瀏覽器中表現一致。可以在事件處理函數中接收這個事件對象,並訪問事件的相關屬性。

範例:訪問事件對象

1
2
3
4
5
6
7
8
9
10
11
function ClickMeButton() {
  function handleClick(event) {
    console.log('事件目標:', event.target);
  }

  return (
    <button onClick={handleClick}>
      點擊我
    </button>
  );
}

在這個範例中,handleClick 函數接收事件對象 event,並可以通過 event.target 訪問事件發生的元素。

4. 事件綁定與 this

在類別組件中,我們通常需要將事件處理函數綁定到 this,以確保在事件處理程序中正確引用組件的 this。有幾種常見的方法來解決 this 綁定問題。

範例:使用 bind 綁定 this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ToggleButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOn: true };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isOn: !prevState.isOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isOn ? '' : ''}
      </button>
    );
  }
}

在這裡,我們在 constructor 中使用 bind 方法將 handleClick 綁定到 this,以便在事件處理函數中能夠正確訪問 this.state

5. 使用箭頭函數自動綁定 this

另一種解決 this 綁定問題的方式是使用箭頭函數,箭頭函數會自動綁定當前的 this

範例:使用箭頭函數綁定 this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class ToggleButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOn: true };
  }

  handleClick = () => {
    this.setState(prevState => ({
      isOn: !prevState.isOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isOn ? '' : ''}
      </button>
    );
  }
}

在這裡,我們將 handleClick 定義為箭頭函數,這樣不需要在 constructor 中顯式綁定 this,同樣可以正確訪問組件的 this.state

6. 事件處理中的預設行為與事件冒泡

有時我們可能需要阻止事件的預設行為或停止事件冒泡。這可以通過在事件處理程序中調用 event.preventDefault()event.stopPropagation() 來實現。

範例:阻止事件的預設行為

1
2
3
4
5
6
7
8
9
10
11
12
function Form() {
  function handleSubmit(event) {
    event.preventDefault();
    alert('表單已提交');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">提交表單</button>
    </form>
  );
}

在這個範例中,handleSubmit 中的 event.preventDefault() 會阻止表單的默認提交行為,從而讓我們可以控制表單提交後的處理邏輯。

範例:阻止事件冒泡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Outer() {
  function handleClick() {
    alert('外層被點擊');
  }

  return (
    <div onClick={handleClick}>
      <Inner />
    </div>
  );
}

function Inner() {
  function handleClick(event) {
    event.stopPropagation();
    alert('內層被點擊');
  }

  return <button onClick={handleClick}>點擊內層</button>;
}

在這裡,當點擊內層按鈕時,event.stopPropagation() 會阻止事件冒泡,從而避免觸發外層的 handleClick

7. 使用事件處理函數更新 State

事件處理程序通常會用來更新組件的狀態。當某些操作(如點擊按鈕)發生時,我們可以通過事件處理函數來改變組件的 state

範例:使用事件處理函數更新 state

1
2
3
4
5
6
7
8
9
10
11
12
13
function ToggleButton() {
  const [isOn, setIsOn] = useState(true);

  function handleClick() {
    setIsOn(!isOn);
  }

  return (
    <button onClick={handleClick}>
      {isOn ? '' : ''}
    </button>
  );
}

在這裡,點擊按鈕時會調用 handleClick 函數,並且會切換按鈕的顯示狀態,從 “開” 變成 “關” 或從 “關” 變成 “開”。


總結

  • 在 React 中,事件處理程序使用駝峰式命名法,並且處理函數通常是函數,而非字串。
  • 事件處理程序可以通過箭頭函數或 bind 方法來傳遞參數或綁定 this
  • React 使用合成事件系統來確保跨瀏覽器的事件行為一致。
  • 我們可以通過 event.preventDefault() 阻止預設行為,或使用 event.stopPropagation() 來阻止事件冒泡。
  • 事件處理通常用來更新組件的狀態,從而改變 UI 的呈現。

React 中的事件處理簡潔而靈活,使得處理各種用戶交互變得簡單高效。

本文章以 CC BY 4.0 授權