2

我很难理解为什么create-react-app无法编译,告诉我error 'updateWord' is not defined no-undef. 我对使用 ES6 进行 React 相当陌生。通常我会写一个类似的组件,const App = React.createClass({ });但我决定尝试一些语法糖。

我有父组件App和一个子组件Input

class App extends Component {
  constructor(props) {
    super(props);
    // all other code omitted...
  }

  handleInput(input) {
    console.log(`handle: ${input}`); 
    updateWord(input);
    // this also causes an error
    // this.updateWord(input);
  }

  updateWord(input) {
    console.log(`update ${input}`);
    // why isn't this defined?
  }

  render() {
    return (
      <div className="App">
        <Input onInput={this.handleInput} />
      </div>
      );
  }
}

class Input extends Component {
  handleInput(e) {
    let input = e.target.value;
    this.props.onInput(input);
  }

  render() {
    return (
      <form>
        <input onChange={this.handleInput.bind(this)} />
      </form>
      );
  }
}

我试过改成this.updateWord(input);而不是updateWord(input)但无济于事。我得到:

"App.js:55 Uncaught TypeError: this.updateWord is not a function" 

通常,当我实现与我现在正在做的类似的模式(使用 ES5)时,我没有任何困难。例如:

const App = React.createClass({
  getInitialState: function() {
    // all other code omitted...
  },

  handleInput: function(input) {
    console.log(`handle: ${input}`); 
    this.updateWord(input);
  },

  updateWord: function(input) {
    console.log(`update ${input}`);
    // In theory, this implementation would not cause any errors?
  },

  render: function() {
    return (
      <div className="App">
        <Input onInput={this.handleInput} />
      </div>
      );
  }
}
4

1 回答 1

2

问题是当你做this.updateWord(...)in时this.handleInputthis指的是Input组件。让我来说明问题:

当您设置onInput处理程序时,如下所示:

onInput={this.handleInput}

在这里,由于您的Input组件正在调用该函数,因此this指的是Input组件。这是由于以下行:

this.props.onInput(input);

Input组件正在调用handleInput. 这意味着,在您的handleInput函数中,this上下文是Input. 考虑这一行:

this.updateWord(input);

handleInput函数中。在这里您调用this.updateWord,但由于thisis Input,它尝试调用updateWordInput存在的调用,从而引发错误。


解决方案是显式地将this上下文绑定为类(App组件)而不是Input组件,使用Function.prototype.bindor 或箭头函数。从文档中:

bind()方法创建一个新函数,在调用该函数时,其this关键字设置为提供的值

您可以像这样应用它:

onInput={this.handleInput.bind(this)}

或者更优选在构造函数中:

this.handleInput = this.handleInput.bind(this);

使用第二个选项,您可以执行以下操作:

onInput={this.handleInput}

(这更可取,因为render方法中的绑定将在每次渲染时创建一个新函数,这不是首选)。

上一行中的this上下文是类。由于您绑定this该类将被正确用作this函数中的上下文,并且执行this.updateWord将调用该类中的方法。

更可取的方法是使用箭头函数而不是常规的 ES6 方法。从文档中:

与函数表达式相比,箭头函数表达式的语法更短,并且不绑定自己的thisargumentssupernew.target

我们可以通过分配handleInput给箭头函数而不是常规方法来应用它:

handleInput = (input) => {
    console.log(`handle: ${input}`); 
    this.updateWord(input);
}

这将bind完全消除使用,而是使用箭头函数。由于箭头函数不绑定自己的this,这意味着this引用封闭的上下文。在上面的示例中,没有使用方法,因此this引用了类(封闭上下文)。这将正确调用类方法updateWord,因此,如果您走这条路线,则无需更改onInput事件处理程序。

于 2016-10-18T19:42:44.777 回答