React Props未定义

时间:2016-11-16 00:26:11

标签: reactjs undefined

我无法理解为什么我的props.updateBuilding无效。

当prop在render方法中时,以下工作

class Buildings extends Component {
  constructor(props) {
      super(props);
  }

  componentWillMount() {
    this.props.fetchBuildings();
  }

  renderBuildings(building) {
    return (
      <div>
          <p> {building.name}</p>
      </div>
    );
  }


  render() {
    return (
      <div> 
        {this.props.buildings.map(this.renderBuildings)}
        <button type="button" className="btn btn-success" onClick={this.props.updateBuilding.bind(this, 1)}>Edit</button>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return { buildings: state.buildings.all };
}
function mapDispatchToProps(dispatch){
  return bindActionCreators({ fetchBuildings, updateBuilding}, dispatch);
}

但是当我将this.props.updateBuilding放到如下所示的renderBuildings方法时......

  renderBuildings(building) {
    return (
      <div>
          <p> {building.name}</p>
          <button type="button" className="btn btn-success" onClick={this.props.updateBuilding.bind(this, building.id)}>Edit</button>
      </div>
    );
  }

我收到错误:

Cannot read property 'props' of undefined

当它在renderBuildings方法中时,似乎无法读取道具updateBuildings并且我不确定是什么原因造成的。

6 个答案:

答案 0 :(得分:16)

就我而言,我忘了将props添加为构造函数的参数。

constructor(props) {
  super(props);
}

答案 1 :(得分:13)

你错过了这个错误。 props未定义,调用props的内容未定义,即this关键字。您可以通过传入第二个参数

手动设置地图功能的上下文

this.props.buildings.map(this.renderBuildings, this)

或将其绑定到内联

this.props.buildings.map(this.renderBuildings.bind(this))

答案 2 :(得分:2)

尝试:

this.props.buildings.map(this.renderBuildings.bind(this))

答案 3 :(得分:2)

在做todo教程时,我也遇到了一些将道具与功能组件一起使用的问题。当使用功能组件而不是类组件时,如果要使用道具,则必须从节点模块进行导入。将此行放在文件顶部:

import props from 'prop-types';

然后,当您要在功能组件中使用道具时,首先需要将关键字作为该函数的参数传递。之后,将允许您像在类组件中一样使用它,但无需使用关键字“ this”

function Todos(props) {
  console.log(props.todos);
  return (
    <div className="Todos">
        <h2>This is the Todos component</h2>
    </div>
  );
}

答案 4 :(得分:0)

不建议您直接在渲染器或组件中除构造函数之外的任何其他位置绑定函数。因为对于每个绑定的函数,都会在webpack捆绑包js文件中创建一个新的函数/对象,因此捆绑包的大小将会增加。您的组件将由于多种原因而重新渲染,例如执行setState时,接收到新道具时,执行this.forceUpdate()等时。因此,如果直接在渲染中绑定函数,它将始终创建一个新函数。而是总是在构造函数中进行函数绑定,并在需要时调用引用。这样,它仅创建一次新函数,因为每个组件只调用一次构造函数。

在构造函数中绑定它们,并使用类似的引用

constructor(props){
    super(props);
    this.renderBuildings = this.renderBuildings.bind(this);
}

this.props.buildings.map(this.renderBuildings)

答案 5 :(得分:0)

不再建议使用内联绑定。现在,您可以完全删除构造函数,而不必在组件上声明方法,而是可以声明属性并将其设置为箭头函数。这会将属性绑定到实例。

在昨天的“面向初学者的反应”课程中,我特别向WES BOS表示了祝贺! :D超级抽水实际上对堆栈溢出有贡献!

renderBuildings = (buildings) => {
//this keyword is now available for use here
}