2014-12-01 68 views
7

注意:此帖已发布到当时React不支持ES6(v12)。React和ES6继承

我有一个ES6类:

class BaseClass { 
    getInitialState(){ 
     return {message: 'Hello!'}; 
    } 

    render() { 
     return (
      <div> 
       <div>{this.state.message}</div> 
      </div> 
     ) 
    } 
} 

我可以在ES6使用这个表达式(来源:react ES6 browserify)出口

export default React.createClass(BaseClass.prototype) 

这工作得很好。现在我想用ES6继承致以BaseClass类:

class ExtendedClass extends BaseClass{ 
    getInitialState(){ 
     return {message: "Hello! I'm an extension"}; 
    } 
} 

但是当我打电话React.createClassExtendedClass类,我得到了以下异常:

Invariant Violation: ReactCompositeComponentInterface: You are attempting to define `constructor` on your component more than once. This conflict may be due to a mixin. 

我知道阵营0.13被认为更ES6友好,但有什么办法来处理?

编辑:

我使用Traceur编译我ES6类。为ExtendedClass输出看起来像:

function ExtendedClass() { 
    "use strict"; 
    if (BaseClass !== null) { 
    BaseClass.apply(this, arguments); 
    } 
} 
for (BaseClass____Key in BaseClass) { 
    if (BaseClass.hasOwnProperty(BaseClass____Key)) { 
     ExtendedClass[BaseClass____Key] = BaseClass[BaseClass____Key]; 
    } 
    } 
    ____SuperProtoOfBaseClass = BaseClass === null ? null : BaseClass.prototype; 
    ExtendedClass.prototype = Object.create(____SuperProtoOfBaseClass); 
    ExtendedClass.prototype.constructor = ExtendedClass; 
    ExtendedClass.__superConstructor__ = BaseClass; 
    ExtendedClass.prototype.getInitialState = function() { 
    "use strict"; 
    return {message: "Hello! I'm an extension"}; 
    }; 
    React.createClass(ExtendedClass.prototype); 
+0

getInitialState不应与ES6代码中使用。相反,在构造函数中设置你的初始状态,'constructor(props){super(props); this.state = {message:'Hello!'}}' – widged 2015-08-04 02:19:00

+0

此帖已发布在React不支持ES6(v12)的时间。它不再相关。当然,使用React v13一切正常,并且不需要使用提到的解决方法。 – JBE 2015-08-04 14:19:50

回答

1

这里是我已经找到了解决办法:

里面React.js库,我已经更新了ReactCompositeComponentInterface添加自定义策略constructor(据我所知有没有办法可以定制的“接口”正常):在ExtendedClass

var ReactCompositeComponentInterface = { 

/** 
* An array of Mixin objects to include when defining your component. 
* 
* @type {array} 
* @optional 
*/ 
mixins: SpecPolicy.DEFINE_MANY, 

/** 
* Custom policy for 'constructor' 
*/ 
constructor: SpecPolicy.DEFINE_MANY, 

    ... 

} 

然后,你必须重新定义每个方法,即使你不自定义他们:

class ExtendedClass extends BaseClass{ 
    getInitialState(){ 
     return {message: "Hello! I'm an extension"}; 
    } 
    /** required */ 
    render(){ 
     return super.render(); 
    } 
} 

我对这个肮脏的解决方案不满意,但它会完成等待0.13版本的工作,希望能解决这些问题。

6

关于在ES6中编写ReactJS有一篇很棒的文章。

http://ilikekillnerds.com/2015/02/developing-react-js-components-using-es6/

反正使用ES6,当你不使用React.createClass。您只需创建延伸React.Component的类

同样在ES6中,您没有getInitialState而不是defaultProps。它被替换为使用this.state内部构造函数。

看看这个例子。假设您有扩展卡组件的卡组件和欢迎面板。

的代码如下:

卡组件:

import React , { Component } from 'react' 
class Card extends Component { 
    constructor(props){ 
    super(props); 
    } 

    render() { 
    return (
     <div className="card"> 
      <div className="card__content"> 
      <label>{this.props.content}</label> 
      </div> 
     </div> 
    ) 
    } 

    initPanel(el,content){ 
    React.render(<Card content={content} />, el); 
    } 
} 

export default Card; 

欢迎面板组件:

import React from 'react'; 
import Card from 'components/card.component'; 

class WelcomePanel extends Card { 
    constructor(props){ 
    super(props); 
    this.state = { 
     content: "Welcome Panel", 
     index: 0 
    } 
    } 

    componentClicked(){ 
    this.setState({content: "Component Clicked", index: this.state.index + 1}) 
    } 

    render() { 
    return (
     <div className="welcome-panel" onClick={this.componentClicked.bind(this)}> 
     <Card content={`${this.state.content} ${this.state.index > 0 ? this.state.index : ''} ${this.state.index > 0 ? 'times' : ''} `} /> 
     </div> 
    ) 
    } 

    initPanel(el,content){ 
    React.render(<WelcomePanel />, el); 
    } 
} 

export default { Class: WelcomePanel }