【问题标题】:React JS - Prop undefined after refactoring to ES6React JS - 重构为 ES6 后的 Prop 未定义
【发布时间】:2018-02-17 02:17:55
【问题描述】:

我一生都无法弄清楚以下代码有什么问题,当用户通过 BugAdd 表单添加错误时,值将传递给 handleSubmit 函数,该函数又应将其 props 传递给 addBug

但是,当我提交表单时,我看到了 'console.log("Adding bug:", bug);'

但在此之后我收到“react.min.js:14 Uncaught TypeError: Cannot read property 'bugs' of undefined”,我最初的想法是我可能在某个地方错过了 .bind。

谁能发现我的代码有问题,在重构为 ES6 之前它运行良好

class BugAdd extends React.Component {
  render() {
    console.log("Rendering BugAdd");
    return (
      <div>
        <form name="bugAdd">
          <input type="text" name="owner" placeholder="Owner" />
          <input type="text" name="title" placeholder="Title" />
          <button onClick={this.handleSubmit.bind(this)}>Add Bug</button>
        </form>
      </div>
    )
  }

  handleSubmit(e) {
    e.preventDefault();
    var form = document.forms.bugAdd;
    this.props.addBug({owner: form.owner.value, title: form.title.value, status: 'New', priority: 'P1'});
    // clear the form for the next input
    form.owner.value = ""; form.title.value = "";
  }
}

class BugList extends React.Component {

  constructor() {
    super();
    this.state = {
      bugs: bugData
    }
  }

  render() {
    console.log("Rendering bug list, num items:", this.state.bugs.length);
    return (
      <div>
        <h1>Bug Tracker</h1>
        <BugFilter />
        <hr />
        <BugTable bugs={this.state.bugs} />
        <BugAdd addBug={this.addBug} />
      </div>
    )
  }

  addBug(bug) {
      console.log("Adding bug:", bug);
      // We're advised not to modify the state, it's immutable. So, make a copy.
      var bugsModified = this.state.bugs.slice();
      bug.id = this.state.bugs.length + 1;
      bugsModified.push(bug);
      this.setState({bugs: bugsModified});
  }
}

【问题讨论】:

  • 你没有绑定this.addBug
  • 第二个组件的 addBugs 方法怎么发现自己在第一个的斜坡上?
  • 您可能想发布您的旧工作代码,以便我们了解您的意图。
  • @ivarni - 伙计...至少我怀疑是对的,即使我看不到它!
  • @James 当您查看代码足够长的时间时,有时很难发现这些东西。正如其中一个答案所建议的那样,您应该在构造函数中绑定函数,这样就不必在每次组件呈现时都绑定它。

标签: reactjs


【解决方案1】:

当您使用 ES6 类扩展 React.Component 时,组件方法不会像使用 React.createClass 时那样自动绑定到 this。您可以在official documentation 中阅读更多相关信息。

在您的情况下,最干净的解决方案是将构造函数中的addBug 方法绑定到组件的this,如下所示:

class BugList extends React.Component {

  constructor() {
    super();
    this.state = {
      bugs: bugData
    }
    this.addBug = this.addBug.bind(this);
  }

  render() {
    console.log("Rendering bug list, num items:", this.state.bugs.length);
    return (
      <div>
        <h1>Bug Tracker</h1>
        <BugFilter />
        <hr />
        <BugTable bugs={this.state.bugs} />
        <BugAdd addBug={this.addBug} />
      </div>
    )
  }

  addBug(bug) {
      console.log("Adding bug:", bug);
      // We're advised not to modify the state, it's immutable. So, make a copy.
      var bugsModified = this.state.bugs.slice();
      bug.id = this.state.bugs.length + 1;
      bugsModified.push(bug);
      this.setState({bugs: bugsModified});
  }
}

现在您可以访问this.state

【讨论】:

  • 非常感谢,当我们需要绑定多个函数的时候呢?我会在构造函数中绑定每一个吗?
  • 是的,需要一一绑定。不幸的是,没有更好的方法。有一个ES7 proposal,你可以在其中使用::this.addBug,但这只是一个语法糖,做的事情完全相同(如果我没记错的话)。
【解决方案2】:

尝试使用=&gt; 定义您的addBug 方法,该方法将自动绑定到类实例:

  addBug = (bug) => {
      console.log("Adding bug:", bug);
      // We're advised not to modify the state, it's immutable. So, make a copy.
      var bugsModified = this.state.bugs.slice();
      bug.id = this.state.bugs.length + 1;
      bugsModified.push(bug);
      this.setState({bugs: bugsModified});
  }

不要忘记将 Class 属性转换添加到您的 babel http://babeljs.io/docs/plugins/transform-class-properties/

【讨论】:

  • 你将需要来自 babel 的类属性转换插件来解析语法
  • @JúliusRetzer 如果有人没有正确设置,你的问题也会出现语法错误。反对票似乎有点苛刻
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 2021-06-23
  • 1970-01-01
  • 2021-04-06
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多