2014-12-01 12 views
7

Hinweis: Dieser Beitrag wurde zum Zeitpunkt veröffentlicht React war nicht unterstützt ES6 (v12).React und ES6 Vererbung

Ich habe eine ES6 Klasse:

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

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

Dass ich in ES6 mit diesem Ausdruck (Quelle: react ES6 browserify) exportieren

export default React.createClass(BaseClass.prototype) 

Dies funktioniert gut. Nun würde Ich mag ES6 Erbe verwenden, um meine BaseClass Klasse zu erweitern:

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

Aber wenn ich React.createClass auf der ExtendedClass Klasse aufrufen, bekam ich die folgende Ausnahme:

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

Ich weiß, 0,13 Reagieren soll mehr ES6-freundlich sein, aber gibt es irgendwelche Möglichkeiten, damit umzugehen?

EDIT:

ich Traceur bin mit meiner ES6 Klassen zu kompilieren. Die Ausgabe für ExtendedClass wie folgt aussieht:

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 nicht mit es6 Code verwendet werden soll. Setzen Sie stattdessen Ihren Anfangszustand im Konstruktor 'constructor (requisiten) {super (reps); this.state = {Nachricht: 'Hallo!'}} ' – widged

+0

Dieser Beitrag wurde zum Zeitpunkt veröffentlicht, an dem REACT ES6 (v12) NICHT unterstützte. Es ist nicht mehr relevant. Natürlich funktioniert mit React v13 alles einwandfrei und es ist nicht nötig die erwähnte Workaround zu verwenden. – JBE

Antwort

1

Hier ist die Abhilfe, die ich gefunden habe:

Innen React.js Bibliothek habe ich die ReactCompositeComponentInterface aktualisiert eine benutzerdefinierte Richtlinie für constructor hinzufügen (Soweit ich weiß, es gibt keinen Weg diese ‚Schnittstelle‘ richtig) anzupassen:

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, 

    ... 

} 

Dann in der ExtendedClass, müssen Sie auch jede Methode neu zu definieren, wenn Sie sie nicht anpassen:

Ich bin nicht glücklich mit dieser schmutzigen Lösung, aber es wird den Job warten auf eine 0.13 Version, die hoffentlich diese Probleme lösen wird.

6

Es gibt einen großen Beitrag über ReactJS in ES6 zu schreiben.

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

Wie dem auch sei, wenn ES6 verwenden Sie verwenden React.createClass nicht. Sie erstellen nur eine Klasse, die erweitert React.Component

Auch in ES6 haben Sie nicht getInitialState nicht defaultProps. Es wurde zugunsten von this.state im Konstruktor ersetzt.

Überprüfen Sie dieses Beispiel aus. Nehmen wir an, Sie haben eine Kartenkomponente und ein Begrüßungsfenster, das die Kartenkomponente erweitert.

Der Code ist wie folgt:

Karte Komponente:

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; 

Welcome Panel-Komponente:

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 } 
Verwandte Themen