在create-react-app中未定义ES6方法

时间:2016-10-18 19:35:16

标签: javascript reactjs es6-class create-react-app

我很难理解为什么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>
      );
  }
}

1 个答案:

答案 0 :(得分:3)

问题是,当您this.updateWord(...) this.handleInput this时,Input会引用onInput组件。让我来说明问题:

设置onInput={this.handleInput} 处理程序时,如下所示:

Input

此处,由于您的this组件正在调用该函数,因此Input引用this.props.onInput(input); 组件。这是由于行:

Input

handleInput组件正在调用handleInput。这意味着,在this函数中,Input上下文为this.updateWord(input); 。考虑一下:

handleInput
this.updateWord函数中的

。在这里,您致电this,但由于InputupdateWord,它会尝试从Input调用不存在的this,从而引发错误。

解决方案是使用{{3}显式绑定App上下文作为类(Input组件)而不是bind()组件或Function.prototype.bind。来自文档:

  

this方法创建一个新函数,在调用时,将onInput={this.handleInput.bind(this)} 关键字设置为提供的值

你可以这样申请:

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

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

onInput={this.handleInput}

使用第二个选项,您可以这样做:

render

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

上面一行中的this上下文是类。由于绑定this将在函数中正确用作this.updateWord上下文,执行this将调用类中的方法< / em>的。

更优选的方法是使用箭头功能而不是常规的ES6方法。来自文档:

  

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

我们可以通过将handleInput = (input) => { console.log(`handle: ${input}`); this.updateWord(input); } 分配给箭头函数而不是常规方法来应用它:

bind

这将完全取消this的使用,而是使用箭头功能。由于箭头函数不会绑定自己的this,因此this表示封闭的上下文。在上面的示例中,未使用方法,因此updateWord引用类(封闭上下文)。这将正确调用类方法onInput,因此,如果你走这条路线,你不需要改变even_strings事件处理程序。