通过props传递给子的React函数是未定义的

时间:2016-11-13 00:04:37

标签: reactjs react-rails

我正在尝试将selectNotebook传递给notebookNav以在onClick()函数中使用。我可以在React dev工具中的prop中看到selectNotebook,但每当我点击一个按钮时,我都会收到错误Uncaught TypeError: Cannot read property 'selectNotebook' of undefined(…)

这是我的父组件:

var App = React.createClass({

  getInitialState: function() {
    return {
      notebooks: this.props.notebooks,
      nav: this.props.nav
    };
  },

  selectNotebook: function(id) {
    const nav = {...this.state.nav};
    nav[notebook] = this.props.notebooks[id];
    this.setState({nav})
  },

  render: function() {
    return (
      <div style={{"height": "100%"}}>
        <NotebookNav 
          notebooks={this.props.notebooks}
          selectNotebook={this.selectNotebook}
        >
        </NotebookNav>
        <Technique></Technique>
      </div>
    );
  }
});

这是子组件:

var NotebookNav = React.createClass({

  render: function() {
    notebooks = this.props.notebooks;

    return (
      <div className="col-md-4">
        <div className="panel panel-info">
          <div className="panel-heading">
            <h4 className="panel-title">Your Notebooks</h4>
          </div>

          <div className="panel-body">
            <ul className="breadcrumb" 
              style={{"backgroundColor": "#fff", "marginBottom": "0"}}
            >
              <li className="active">
                notebooks
              </li>
            </ul>

            <ul className="nav nav-pills nav-stacked">
              <div className="btn-group-vertical" style={{"width": "100%"}}>
                {notebooks.map( function (notebook) {
                  return(
                    <li 
                      key={notebook.id} 
                      className="btn btn-block btn-raised btn-lg"
                      onClick={() => this.props.selectNotebook(notebook.id)}
                    >
                      {notebook.name}
                    </li>
                  );
                })}
              </div>
            </ul>
          </div>
        </div>
      </div>
    );
  }
});

2 个答案:

答案 0 :(得分:1)

      <div className="btn-group-vertical" style={{"width": "100%"}}>
        {notebooks.map( function (notebook) {
          return(
            <li 
              key={notebook.id} 
              className="btn btn-block btn-raised btn-lg"
              onClick={() => this.props.selectNotebook(notebook.id)}
            >
              {notebook.name}
            </li>
          );
        })}
      </div>

问题是传递给map的转换函数会创建它自己的范围,其中this未定义。要解决此问题,Array.prototype.map会为您从外部范围传递this的范围采用第二个参数:

{notebooks.map(function (notebook) { ... }, this)

如果您的目标环境支持它,您还可以使用箭头函数,它隐式使用外部范围:

{notebooks.map((notebook) => { ... })}

答案 1 :(得分:1)

尝试通过绑定传递它: -

<NotebookNav 
      notebooks={this.props.notebooks}
      selectNotebook={this.selectNotebook.bind(this)}
    >

然后在你的子元素上使用箭头函数,使其绑定: -

{notebooks.map( (notebook) => {
      return(
        <li 
          key={notebook.id} 
          className="btn btn-block btn-raised btn-lg"
          onClick={() => this.props.selectNotebook(notebook.id)}
        >
          {notebook.name}
        </li>
      );
    })}