得到"无法读取未定义的属性"反应成分写的是ES6

时间:2015-08-06 14:19:45

标签: javascript reactjs ecmascript-6 react-jsx babeljs

我正在学习React。我正在阅读使用ES5的教程系列。我试图在ES6中编写我的组件,当我查看React关于它的文档时,这似乎是一个简单明了的过程。

这是给我问题的代码:

import React from 'react';

import Button from './button';
import ListItem from './list-item';

export default class DropDown extends React.Component {
    constructor() {
        super();
        this.state = {open: false};
    }

    handleClick() {
        this.state.open = true;
    }

    render() {

        var list = this.props.items.map((item) => {
            return <ListItem item={item}/>
        });

        return (
            <div className="dropdown">
                <Button onClick={this.handleClick} className='btn-default' title={this.props.title}
                        subTitleClassName='caret'/>

                <ul className={'dropdown-menu ' + (this.state.open ? "show" : "") }>
                    {list}
                </ul>
            </div>
        )
    }

}

我在

获得TypeError: Cannot read property 'state' of undefined

handleClick() { this.state.open = true; }

每当我点击Chrome中的按钮时。 谁能告诉我为什么this未定义,或者我做错了什么?

我应该提一下,我使用Babelify将其转换为ES5,作为我的gulp / browserify构建过程的一部分。

2 个答案:

答案 0 :(得分:1)

您收到此错误的原因是因为&#39;这个&#39;在es6中没有为我们自动响应,因为它在es5 createClass中。我们可以使用bind来解决这个问题,或者我们可以使用箭头函数。在您的button元素中,尝试以下操作:

<Button 
  onClick={(e) => this.handleClick(e)} 
  className='btn-default' 
  title={this.props.title}
  subTitleClassName='caret'
/>

答案 1 :(得分:1)

正如在接受的答案中提到的那样,问题在于将功能绑定到组件实例。但是,使用箭头函数的最简单方法并不总是被认为是最佳实践,因为在每个渲染上为Button的prop创建了一个新函数(在某些优化方法中可能很敏感)。因此,您可以使用绑定构造方法:

class Foo extends Component {
  constructor(props) {
    super(props);
    this.methodName = this.methodName.bind(this);
  }
  methodName(e) {
    // handle click
  }
  render() {
    return <Button onClick={this.methodName} />;
  }
}

通过这种方式,你可以保持渲染方法,通过反应来调用,从构建代码中更清晰。