Responsiveness and Inheritance of ES6

Note: This post was published at a time when React did not support ES6 (v12).

I have an ES6 class:

class BaseClass { getInitialState(){ return {message: 'Hello!'}; } render() { return ( <div> <div>{this.state.message}</div> </div> ) } } 

What can I export to ES6 using this expression (source: respond to ES6 )

 export default React.createClass(BaseClass.prototype) 

It works great. Now I would like to use ES6 inheritance to extend the BaseClass class:

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

But when I call React.createClass in the ExtendedClass class, I got the following exception:

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

I know that React 0.13 should be more ES6 friendly, but are there any ways to handle this?

EDIT:

I use Traceur to compile my ES6 classes. The output for ExtendedClass as follows:

 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); 
+7
javascript ecmascript-6 reactjs traceur
source share
2 answers

There is a great article about writing ReactJS in ES6.

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

In any case, when using ES6, you are not using React.createClass. you just create a class that extends React.Component

Also in ES6 you don't have getInitialState, not defaultProps. it is replaced in favor of using this.state inside the constructor.

Check out this example. Let's say you have a map component and a welcome panel that extends the map component.

The code is as follows:

Card Component:

 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 component:

 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 } 
+6
source share

Here is the workaround I found:

Inside the React.js library React.js I updated the ReactCompositeComponentInterface to add a custom policy for constructor (as far as I know, there is no way to properly configure this "interface"):

 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, ... } 

Then in ExtendedClass you need to override each method, even if you don't configure it:

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

I am not happy with this dirty solution, but it will do the work in anticipation of version 0.13, which I hope will solve these problems.

+1
source share

All Articles