【问题标题】:ES6 method is not defined in create-react-appES6 方法未在 create-react-app 中定义
【发布时间】:2016-10-18 19:35:15
【问题描述】:

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

【问题讨论】:

  • 抱歉,仍有问题。我将方法更改为updateWord,当我尝试以updateWord(input) 调用该方法时,如果我尝试将其调用为this.updateWord(input),我仍然得到“错误'updateWord'未定义no-undef”,我得到错误“ App.js:55 Uncaught TypeError: this.updateWord is not a function" @AndrewLi 抱歉,我现在更新我的问题....
  • 不,我认为双方都有误解 :( 我以为你的建议解决了我的问题,所以我跳了枪。重命名更新方法时我仍然有这个问题。@AndrewLi
  • 没问题@AndrewLi
  • @AndrewLi 是的,我仍然得到“App.js:61 Uncaught TypeError: this.updateWord is not a function”
  • 我想我明白了。使用this.updateWord,然后将onInput更改为{this.handleInput.bind(this)}

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


【解决方案1】:

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

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

onInput={this.handleInput}

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

this.props.onInput(input);

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

this.updateWord(input);

handleInput 函数中。这里调用this.updateWord,但是由于thisInput,它会尝试从不存在的Input调用updateWord,从而抛出错误。


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

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

你可以这样应用它:

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

或者最好在构造函数中:

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

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

onInput={this.handleInput}

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

上面一行中的this 上下文就是类。由于绑定了thisclass 将被正确地用作函数中的this 上下文,执行this.updateWord 将调用class 中的方法。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    相关资源
    最近更新 更多