【问题标题】:React Props is Not DefinedReact Props 未定义
【发布时间】:2017-03-30 01:25:28
【问题描述】:

我无法理解为什么我的 props.updateBuilding 不起作用。

当道具在渲染方法中时,以下工作

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,我不确定是什么原因造成的。

【问题讨论】:

    标签: reactjs undefined


    【解决方案1】:

    在我的例子中,我忘记将 props 作为参数添加到构造函数中。

    constructor(props) {
      super(props);
    }
    

    【讨论】:

    • 这是我在扩展基类时使用的。
    【解决方案2】:

    你错过了这个错误。 props 不是未定义的,调用props 的是未定义的,即this 关键字。您可以通过传入第二个参数来手动设置 map 函数的上下文

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

    或内联绑定

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

    【讨论】:

      【解决方案3】:

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

      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>
        );
      }
      

      【讨论】:

      • 隐藏导入的 props 变量对我来说似乎是个非常糟糕的主意... Prop 类型通常导入为 PropTypes 并且是一个完全不同的概念。它允许您为组件道具定义所需的类型以帮助开发。请参阅道具类型文档here。功能组件所需的只是将props 定义为您的函数的参数(就像您拥有的那样)。您绝对不需要导入 'prop-types' 来执行此操作。
      【解决方案4】:

      试试:

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

      【讨论】:

        【解决方案5】:

        不建议直接在render中或组件中除构造函数之外的任何地方绑定函数。因为对于每个函数绑定,都会在 webpack bundle js 文件中创建一个新的函数/对象,因此 bundle 的大小会增加。您的组件将出于多种原因重新渲染,例如您执行 setState 时、收到新道具时、执行 this.forceUpdate() 时等。因此,如果您直接在渲染中绑定您的函数,它将始终创建一个新函数。相反,总是在构造函数中进行函数绑定,并在需要的地方调用引用。通过这种方式,它只创建一次新函数,因为每个组件只调用一次构造函数。

        在构造函数中绑定它们并像使用引用一样

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

        【讨论】:

          【解决方案6】:

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

          特别感谢 WES BOS 昨天在他的 React for Beginners 课程中教给我的! :D 超级兴奋,实际上可以为 Stack Overflow 做出贡献!

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

          【讨论】:

            【解决方案7】:

            我只是错过了 this 关键字 this.props.buildings

            【讨论】:

              猜你喜欢
              • 2020-10-16
              • 2017-12-04
              • 1970-01-01
              • 2018-01-24
              • 1970-01-01
              • 1970-01-01
              • 2021-01-15
              • 2016-11-23
              • 1970-01-01
              相关资源
              最近更新 更多