2017-06-05 18 views
0

我正在准备升级到React 16的React组件,其中关键是要更新与React.createClass一起使用class关键字的组件。从createClass转换为class关键字时,如何正确绑定React组件类的事件处理程序?

当我遇到Can only update a mounted or mounting component错误时,遇到引发类方法的事件处理程序时,我遇到了麻烦。使用React.createClass

一个简单的例子...

原来的分量:

const Foo = React.createClass({ 
    getInitialState() { 
    return { bar: false }; 
    }, 

    onClick() { 
    this.setState({ bar: !this.state.bar }); 
    }, 

    render() { 
    return (
     <div> 
     <p>{this.state.bar ? 'YAY' : 'BOO'}</p> 
     <button onClick={this.onClick}>CLICK IT</button> 
     </div> 
    ); 
    }, 
}); 

按预期工作。那么,这是否,如果我愿意忽略一个新的函数对象将与每次调用创建render

class Foo extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { bar: false }; 
    } 

    render() { 
    return (
     <div> 
     <p>{this.state.bar ? 'YAY' : 'BOO'}</p> 
     <button onClick={() => { this.setState({ bar: !this.state.bar }); }}>CLICK IT</button> 
     </div> 
    ); 
    } 
} 

但是,我不能得到的“在构造函数中结合”的工作方式:

class Foo extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { bar: false }; 

    this.onClick = this.onClick.bind(this); 
    } 

    onClick() { 
    this.setState({ bar: !this.state.bar }); 
    } 

    render() { 
    return (
     <div> 
     <p>{this.state.bar ? 'YAY' : 'BOO'}</p> 
     <button onClick={this.onClick}>CLICK IT</button> 
     </div> 
    ); 
    } 
} 

我也不能获得属性初始化语法的工作方式:

class Foo extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { bar: false }; 
    } 

    onClick =() => { 
    this.setState({ bar: !this.state.bar }); 
    } 

    render() { 
    return (
     <div> 
     <p>{this.state.bar ? 'YAY' : 'BOO'}</p> 
     <button onClick={this.onClick}>CLICK IT</button> 
     </div> 
    ); 
    } 
} 

在这两种这些情况下,每当我按一下按钮前面提到的错误消息显示了我浏览器控制台。

我希望有人自己已经遇到过这个问题,并且就如何处理它提出了建议。我想,这完全忽略了一些微不足道的东西。 :)

在此先感谢!

+0

你可以尝试'的onClick(){ this.setState((prevState)=>({吧!prevState.bar})); }' –

+1

这是一个单独的问题;任何绑定方法都能正常工作 –

+1

要使类属性有效,您需要对其进行转换。它们现在不包含在Babel预设中,因为它们仍然是一个建议。你需要启用[stage-2](https://babeljs.io/docs/plugins/preset-stage-2/)。 –

回答

0

查看React文档:他们有相同的例子。顺便说一句你的绑定例子适用于我:发布你的错误信息。

class Toggle extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = {isToggleOn: true}; 

    // This binding is necessary to make `this` work in the callback 
    this.handleClick = this.handleClick.bind(this); 
    } 

    handleClick() { 
    this.setState(prevState => ({ 
     isToggleOn: !prevState.isToggleOn 
    })); 
    } 

    render() { 
     return (
     <button onClick={this.handleClick}> 
      {this.state.isToggleOn ? 'ON' : 'OFF'} 
     </button> 
    ); 
    } 
    } 

    ReactDOM.render(
    <Toggle />, 
    document.getElementById('root') 
); 
+0

错误信息非常标准:“警告:setState(...):只能更新挂载或挂载的组件,这通常意味着你在挂载的组件上调用了setState(),这是一个no-op。代码为Foo组件。“ – natlee75

+0

我在准系统'create-react-app'应用程序中进行了测试,并验证它在那里工作,所以这只是应用程序设置的一个问题。谢谢! – natlee75

0

Pshh,做它的简单方法和使用react-autobind。在构造函数中自动将所有组件函数绑定到this

超级简单易用:

import autoBind from 'react-autobind'; 

constructor() { 
    super(); 
    autoBind(this); 
} 
+0

这听起来像是作弊! ;) 非常认真,我认为这不会奏效。我试图查明应用程序存在问题。该语法是正确的,因为我可以让这个类在一个准系统'create-react-app'应用程序中工作,所以还有其他的事情正在搞砸React组件如何绑定。 – natlee75

0

从电子应用到网络移植一些代码后有这个确切的问题。

"transform-es2015-classes"是你需要的!

npm install --save-dev babel-plugin-transform-es2015-classes

更多信息@的babel docs

相关问题