簡體   English   中英

事件處理:基於功能的組件與基於類的組件

[英]Event handling: functional based component vs class based component

這是我的第一個React App(react@16.8.1)。 我試圖找出為什么在使用基於功能的組件與基於類的組件時onClick事件的處理方式不同。

據我所知,我應該使用基於類的c。 只有當我需要改變狀態時,對嗎?

基於功能的組件將引發_this is undefined error但基於類-不是。

在兩種情況下,我都使用箭頭功能而不是綁定功能。

基於功能:

import React from 'react';

const AnswersDisplay = (props) => {
// even with bind I still get "_this is undefined"
//this.onAnswer = this.onAnswer.bind(this); 

  const answerList = props.answerList.map( (option) => {
    return (
      <button
        onClick={this.onAnswer}
        value={option}
        className="ui basic green button">{option}
      </button>
    )
  }); 

  const onAnswer = (e) =>{
    console.log(e.target.value);
  }

  return(
    <div className="ui two buttons hSpace">{this.answerList}</div>
  );
};

export default AnswersDisplay;

與基於類的作品。

import React from 'react';

class AnswersDisplay extends React.Component {
  constructor(props) {
    super(props);
    //this.onAnswer = this.onAnswer.bind(this);
  }

  answerList = this.props.answerList.map( (option) => {
    return (
      <button
        onClick={this.onAnswer}
        value={option}
        className="ui basic green button">{option}
      </button>
    )
  });

  onAnswer = (e) =>{
    console.log(e.target.value);
  }

  render() {
    return(
        <div className="ui two buttons hSpace">{this.answerList}</div>
    );
  }
};


export default AnswersDisplay;

對於功能組件,您要聲明一個常量,並在其中保留一個函數。 單擊按鈕時要呼叫的對象。 但要確保的使用this一個功能。 this將涉及全球執行上下文在這種情況下,在這種特定情況下,JavaScript引擎將無法找到一個屬性onAnswer所以它會返回undefined

為了使這項工作奏效,您沒有this請求就回叫。

這樣: onClick={onAnswer}

總體而言,代碼如下所示:

import React from 'react';

const AnswersDisplay = (props) => {
// even with bind I still get "_this is undefined"
//this.onAnswer = this.onAnswer.bind(this); 

  const answerList = props.answerList.map( (option) => {
    return (
      <button
        onClick={onAnswer}
        value={option}
        className="ui basic green button">{option}
      </button>
    )
  }); 

  const onAnswer = (e) =>{
    console.log(e.target.value);
  }

  return(
    <div className="ui two buttons hSpace">{this.answerList}</div>
  );
};

MDN網絡文檔涵蓋了你需要知道的一切this

為了保持它的簡單,想的來講objects ,其中this是“不確定的”,除非:

  • 方法/函數已通過ES5的bind(this)綁定到object (請參閱下面的注釋),或者通過將外部函數與object本身重新綁定而反彈到object外部: bind(obj)

注意 :如下面所示(在method6),有其中使用ES5異常arrow functions的內部object意味着它會保留在包封詞法作用域this而不需要被約束。

例如:

 this.prop = "global prop" const outsideArrowFunction = () => (this.prop) function outsideFunction() { return this.prop; }; const obj = { prop: "obj's prop", method: function() { return this.prop; // returns "obj's prop" }, method2: function() { return this; // returns the entire "obj" and its properties }, method3: function() { return this.method(); // returns "obj's prop" }, method4: function() { return outsideFunction(); // returns "global prop" because the outsideFunction's lexical scope doesn't recognize the "obj"'s nor its properties }, method5: function() { return outsideArrowFunction(); // same as method4, utilizes global this }, method6: function() { const x = () => this.method(); return x(); // returns "obj's prop" because arrow functions take on "this" from the "obj" }, method7: function() { const x = function() { return this.prop; }; return x(); // returns "global prop" because "this" loses lexical scope upon execution }, method8: function() { const x = this.method.bind(this); return x(); // returns "obj's prop" because "this" refers to the "obj" upon execution }, method9: function(callback) { return callback(this.method); }, method10: function() { return this.method9(function(callback) { return callback(); // returns "global prop" because "this" loses lexical scope upon execution }); } }; const a = outsideArrowFunction.bind(obj); // returns "global prop" because arrow functions take on whatever "this" is upon its creation, so "this" refers to the global "this" const b = outsideFunction.bind(obj); // returns "obj's prop" since a traditional function can rebind "this", which has been rebound to "obj" console.log(`Method: ${obj.method()}`); console.log(`Method2: ${obj.method2()}`); console.log(`Method3: ${obj.method3()}`); console.log(`Method4: ${obj.method4()}`); console.log(`Method5: ${obj.method5()}`); console.log(`Method6: ${obj.method6()}`); console.log(`Method7: ${obj.method7()}`); console.log(`Method8: ${obj.method8()}`); console.log(`Method10: ${obj.method10()}`); console.log(`arrowFunction: ${a()}`); console.log(`outsideFunction: ${b()}`); 

說到classes ,它們是objects的模板。 因此, this將是undefined或者是一個全球性的this除非類method已經在被綁定constructor或您使用arrow function 通過單擊每個按鈕來嘗試下面的示例,請注意所有3種方法如何工作,但這取決於它們的調用方式

 class Example extends React.Component { constructor() { super(); this.state = { method: "" }; this.boundMethod = this.boundMethod.bind(this); } componentDidMount() { this.unboundMethod(); }; boundMethod() { this.setState({ method: "Bound Method" }); // this works because the method is bound to the class } unboundMethod() { try { this.setState({ method: "Unbound Method" }); // this only works if it's called within a bound method class (like componentDidMount) } catch (err) { alert(err); // however, if it's called within a callback (like in an onClick event), it fails. } } arrowMethod = () => { this.setState({ method: "Arrow Method" }); // this works because arrow methods are automatically bound to the class }; render() { return ( <div> <button onClick={this.boundMethod}>Bound Method</button> <button onClick={this.unboundMethod}>Unbound Method</button> <button onClick={this.arrowMethod}>Arrow Method</button> <p>The {this.state.method} was called</p> </div> ); }; } ReactDOM.render(<Example />, document.body); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM