Reactjs Material UI 状态在事件中未定义

Posted

技术标签:

【中文标题】Reactjs Material UI 状态在事件中未定义【英文标题】:Reactjs Material UI state is undefined on event 【发布时间】:2016-04-04 16:11:38 【问题描述】:

我正在使用 react 和 material ui 构建一个简单的应用程序

主要组件

'use strict';

import React from 'react';
import ProjectList from './projectlist';

export default class Application extends React.Component 
    constructor(props) 
        super(props);
    

    changeProject() 
    

    render() 
        return <div className="row">
                <div className="col s3">
                    <ProjectList
                        onProjectChangeEvent=this.changeProject/>
                </div>
            </div>;
    

项目列表组件

'use strict';

import React from 'react';
import Card from 'material-ui/lib/card/card';
import CardHeader from 'material-ui/lib/card/card-header';
import CardText from 'material-ui/lib/card/card-text';
import FlatButton from 'material-ui/lib/flat-button';
import CardActions from 'material-ui/lib/card/card-actions';

// FIXME: Remove when react1.0 is launched
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

export default class ProjectList extends React.Component 
    constructor(props) 
        super(props);

        this.state = 
            data: props.data || [],
            changeEvent: props.onProjectChangeEvent
        ;
    

    componentDidMount() 

    

    openEdit = () => 
        console.debug(this.state);   
    

    render() 
        return <Card>
                    <CardHeader
                        title="Super Project Title"
                        subtitle="Super Project Subtitle"/>
                    <CardText>
                        Something important
                    </CardText>
                    <CardActions>
                        <FlatButton
                            label="Edit"
                            onTouchTap=this.openEdit/>
                    </CardActions>
                </Card>;
    

当我单击 FlatButton 时,console.debug(this.state) == undefined?如何从 ProjectList 组件与 Application 组件进行通信?我想将项目对象发送回应用程序。在构造函数内部存在 props,componentDidMount 也是如此。但如果它是未定义的。怎么会?

更新 添加@taylorc93 建议的更改会在控制台中出现此错误

Uncaught (in promise) Error: http://localhost:3000/app/components/projectlist.js: Unexpected token (31:13)
  29 |     
  30 | 
> 31 |     openEdit = () => 
     |              ^
  32 |         console.debug(this.state);   
  33 |     

【问题讨论】:

【参考方案1】:

定义你的函数为

openEdit() 
  console.debug(this.state);   

然后你可以在构造函数中绑定它:

constructor(props) 
  super(props);
  this.openEdit = this.openEdit.bind(this);

并正常引用:

<FlatButton label="Edit" onTouchTap=this.openEdit />

或者只是在你引用它时绑定它(无需更改构造函数):

<FlatButton label="Edit" onTouchTap=this.openEdit.bind(this) />

【讨论】:

【参考方案2】:

随着 ES6 类的变化,React 不再自动将 this 绑定到组件的所有方法,而只是将 render、构造函数和生命周期方法绑定。 https://facebook.github.io/react/docs/reusable-components.html#no-autobinding

因此,当openEdit 被触发时,this 未设置为您的反应组件。解决这个问题的最简单方法是使用 ES6 箭头函数的巧妙技巧,如下所示:

openEdit = () => 
  console.debug(this.state);   

这利用了箭头函数提供的词法 this 绑定,并将 this 正确绑定到您的反应组件。这可能会让您感兴趣以进一步阅读:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

希望所有这些对您有所帮助!

【讨论】:

谢谢,我试过了,但现在控制台出现错误,我已经更新了帖子 抱歉,忘记了类的属性初始化器是 ES7 的特性。如果您仍然想使用它(我觉得它更干净),您可以在您的转译器中启用它。如果您使用的是 babel,这意味着启用第 0 阶段提案【参考方案3】:

这样写:

openEdit () 
     console.debug(this.state);   
   

【讨论】:

虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性的 cmets 挤满你的代码,这会降低代码和解释的可读性! 这是我的第一个答案。下次我会记住这一点。谢谢!

以上是关于Reactjs Material UI 状态在事件中未定义的主要内容,如果未能解决你的问题,请参考以下文章

Reactjs onMouseOver 和 onMouseOut 事件循环在尝试 Popover

ReactJS + Material-UI:如何在 Material-UI <Table/> 的 <TableRow/> 之间交替颜色?

ReactJS + Material-UI:如何减小 Material-UI 的 <TableRow/> 的列宽?

数据变化时如何在ReactJS中刷新Material-Table(Material-ui)组件

如何在 Material-UI、ReactJS 中从分页中设置分页项的样式?

ReactJS + Material-UI:如何使用 Material-UI 的 <DatePicker> 将当前日期设置为默认值?