react的onClick執行函式和bind(this)問題
HTML 通常寫法是:
<button onclick="activateLasers()"> 啟用按鈕 </button>
React 中寫法為:
<button onClick={activateLasers}> 啟用按鈕 </button>
看以上會發現react傳入的是函式名,不加(),如果加了會直接執行。
關於bind
1當你使用 ES6 class 語法來定義一個元件的時候,事件處理器會成為類的一個方法
2你必須謹慎對待 JSX 回撥函式中的 this,類的方法預設是不會繫結 this 的。如果你忘記繫結 this.handleClick 並把它傳入 onClick, 當你呼叫這個函式的時候 this 的值會是 undefined。預設的this指向的是全域性,全域性中沒有你定義在組建裡面的函式。bind後的this指向的是上下文,也就是這個元件,這個元件才有你所需要的方法
3這並不是 React 的特殊行為;它是函式如何在 JavaScript 中執行的一部分。通常情況下,如果你沒有在方法後面新增 () ,例如 onClick={this.handleClick},你應該為這個方法繫結 this。
4在建構函式中bindthis或者在onclick呼叫的時候bind
this.handleClick = this.handleClick.bind(this);
5還可以如果使用 bind 讓你很煩,這裡有兩種方式可以解決。如果你正在使用實驗性的屬性初始化器語法,你可以使用屬性初始化器來正確的繫結回撥函式:
class LoggingButton extends React.Component { // 這個語法確保了 `this` 繫結在 handleClick 中 // 這裡只是一個測試 handleClick = () => { console.log('this is:', this); } render() { return ( <button onClick={this.handleClick}> Click me </button> ); } }
如果你沒有使用屬性初始化器語法,你可以在回撥函式中使用 箭頭函式:
class LoggingButton extends React.Component { handleClick() { console.log('this is:', this); } render() { // 這個語法確保了 `this` 繫結在 handleClick 中 return ( <button onClick={(e) => this.handleClick(e)}> Click me </button> ); } }
這個是一個其他總結
this.x = 9; var module = { x: 81, getX: function() { return this.x; } }; module.getX(); // 返回 81 var retrieveX = module.getX; retrieveX(); // 返回 9, 在這種情況下,"this"指向全域性作用域 // 建立一個新函式,將"this"繫結到module物件 // 新手可能會被全域性的x變數和module裡的屬性x所迷惑 var boundGetX = retrieveX.bind(module); boundGetX(); // 返回 81
即使用bind()方法是為了將函式中的this與當前元件繫結,在該處理函式中的this時刻都指向該元件,避免出現問題。
同時,如今進行this繫結除了bind外還有其他兩種方式
建構函式內繫結
在建構函式 constructor 內繫結this,好處是僅需要繫結一次,避免每次渲染時都要重新繫結,函式在別處複用時也無需再次繫結
import React, {Component} from 'react' class Test extends React.Component { constructor (props) { super(props) this.state = {message: 'Allo!'} this.handleClick = this.handleClick.bind(this) } handleClick (e) { console.log(this.state.message) } render () { return ( <div> <button onClick={ this.handleClick }>Say Hello</button> </div> ) } }
箭頭函式方式
箭頭函式則會捕獲其所在上下文的this值,作為自己的this值,使用箭頭函式就不用擔心函式內的this不是指向元件內部了。可以按下面這種方式使用箭頭函式:
class Test extends React.Component { constructor (props) { super(props) this.state = {message: 'Allo!'} } handleClick (e) { console.log(this.state.message) } render () { return ( <div> <button onClick={ ()=>{ this.handleClick() } }>Say Hello</button> </div> ) } }