Note: This post has been posted at the time React was NOT supporting ES6 (v12).
I have an ES6 class :
class BaseClass {
getInitialState(){
return {message: 'Hello!'};
}
render() {
return (
<div>
<div>{this.state.message}</div>
</div>
)
}
}
That I can export in ES6 using this expression (source : react ES6 browserify)
export default React.createClass(BaseClass.prototype)
This works fine. Now I would like to use ES6 inheritance to extend my BaseClass
class :
class ExtendedClass extends BaseClass{
getInitialState(){
return {message: "Hello! I'm an extension"};
}
}
But when I call React.createClass
on the ExtendedClass
class, I got the following exception :
Invariant Violation: ReactCompositeComponentInterface: You are attempting to define `constructor` on your ponent more than once. This conflict may be due to a mixin.
I know React 0.13 is supposed to be more ES6 friendly but is there any ways to handle that ?
EDIT:
I'm using Traceur to pile my ES6 classes. The output for ExtendedClass
looks like :
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);
Note: This post has been posted at the time React was NOT supporting ES6 (v12).
I have an ES6 class :
class BaseClass {
getInitialState(){
return {message: 'Hello!'};
}
render() {
return (
<div>
<div>{this.state.message}</div>
</div>
)
}
}
That I can export in ES6 using this expression (source : react ES6 browserify)
export default React.createClass(BaseClass.prototype)
This works fine. Now I would like to use ES6 inheritance to extend my BaseClass
class :
class ExtendedClass extends BaseClass{
getInitialState(){
return {message: "Hello! I'm an extension"};
}
}
But when I call React.createClass
on the ExtendedClass
class, I got the following exception :
Invariant Violation: ReactCompositeComponentInterface: You are attempting to define `constructor` on your ponent more than once. This conflict may be due to a mixin.
I know React 0.13 is supposed to be more ES6 friendly but is there any ways to handle that ?
EDIT:
I'm using Traceur to pile my ES6 classes. The output for ExtendedClass
looks like :
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);
Share
Improve this question
edited Dec 13, 2016 at 14:22
JBE
asked Dec 1, 2014 at 17:06
JBEJBE
12.6k7 gold badges51 silver badges52 bronze badges
2
-
getInitialState should not be used with es6 code. Instead, set your initial state in the constructor,
constructor(props) { super(props); this.state = {message: 'Hello!'} }
– widged Commented Aug 4, 2015 at 2:19 - This post has been posted at the time React was NOT supporting ES6 (v12). It is not relevant anymore. Of course with React v13 everything works fine and there is no need to use the workaround mentionned. – JBE Commented Aug 4, 2015 at 14:19
2 Answers
Reset to default 6There is a great post about writing ReactJS in ES6.
http://ilikekillnerds./2015/02/developing-react-js-ponents-using-es6/
Anyway when using ES6 you don't use React.createClass. you just create class that extends React.Component
Also in ES6 you don't have getInitialState not defaultProps. it's replaced in favor using this.state inside constructor.
Check out this example. Let's say you have Card ponent and Wele Panel that extends Card ponent.
The code is as following:
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;
Wele Panel Component:
import React from 'react';
import Card from 'ponents/card.ponent';
class WelePanel extends Card {
constructor(props){
super(props);
this.state = {
content: "Wele Panel",
index: 0
}
}
ponentClicked(){
this.setState({content: "Component Clicked", index: this.state.index + 1})
}
render() {
return (
<div className="wele-panel" onClick={this.ponentClicked.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( <WelePanel />, el);
}
}
export default { Class: WelePanel }
Here is the workaround I've found :
Inside React.js
library, I've updated the ReactCompositeComponentInterface
to add a custom policy for constructor
(As far as I know there's no way to customize this 'interface' properly) :
var ReactCompositeComponentInterface = {
/**
* An array of Mixin objects to include when defining your ponent.
*
* @type {array}
* @optional
*/
mixins: SpecPolicy.DEFINE_MANY,
/**
* Custom policy for 'constructor'
*/
constructor: SpecPolicy.DEFINE_MANY,
...
}
Then in the ExtendedClass
, you have to redefine every method even if you don't customize them :
class ExtendedClass extends BaseClass{
getInitialState(){
return {message: "Hello! I'm an extension"};
}
/** required */
render(){
return super.render();
}
}
I'm not happy with this dirty solution but it will do the job waiting for a 0.13 version that hopefully will solve those issues.