3

I have an existing React component created by React.createClass method. I want to reuse that React component by using class extend feature in ES6 (for method overriding purpose) but the result is unexpected. Example:

//an existing React component created via React.createClass
var ab = React.createClass({
    say(){
        console.log('ab class')
    },
    render(){
        return null;
    }
});

class c1 extends ab {
    say(){
        console.log('c1 class')
    };
}

o = new c1();
console.log(o.say()); //The expected console output is "c1 class" 
                      //but its showing "ab class"
5
  • 1
    afaik theres no way to extend new off old syntax. However its really easy to convert your old component to ES6 the syntax is very similar Commented Mar 10, 2016 at 6:54
  • Sorry, I don't get your point. I'm using babel javascript compilier to convert ES6 syntax so it should not be syntax problem. My problem is the method say() implemented in both class ab and c1 is not override as expected Commented Mar 10, 2016 at 7:03
  • React classes != ES6 classes - they're completely different things, the former is specific to React, the latter is just a standard JavaScript construct. As @LukeMcGregor said, you can't extend an old style component with an ES6 one, at least not with the ES6 extends syntax. Your only option is probably to update ab to an ES6 class if you want to extend it like that. Commented Mar 10, 2016 at 14:57
  • @JoeClay, could you please give me an example code to update "ab" to an ES6 class? Commented Mar 10, 2016 at 15:28
  • @HungTran - Posted as an answer! Commented Mar 10, 2016 at 15:30

1 Answer 1

4

React classes are not the same as ES6 classes - the former is specific to React, the latter is just a standard JavaScript construct. As LukeMcGregor said, you can't extend an old style component with an ES6 one, at least not with the ES6 extends syntax. Your only option is probably to update ab to an ES6 class if you want to extend it like that:

import React from "react";

class ab extends React.Component {
    say() {
        console.log('ab class')
    }

    render() {
        return null;
    }
}

class c1 extends ab {
    say() {
        console.log('c1 class')
    }
}

There are a few caveats to consider when using ES6 classes rather than React classes, namely the lack of the autobinding feature the latter provides. More info, and ways to work around it can be found here: http://www.ian-thomas.net/autobinding-react-and-es6-classes/.

EDIT: Okay, seeing as you can't edit the original class, here's another idea (honestly, it's probably a better idea than extending an existing component). A common concept in React is that of 'Composition' - this is where you create a component that wraps around an existing one. A component created in this way is often referred to as a 'higher order component'; in your case, it might look something like this:

import React from "react";

var ab = React.createClass({
    say() {
        console.log('ab class')
    },

    render() {
        return (<div>I am the AB class</div>);
    }
});

class c1 extends React.Component {
    say() {
        console.log('c1 class')
    };

    render() {
        return (<ab />);
    }
}

This may seem like it doesn't approximate inheritance, but you can actually do a lot with it - if you want to pass data back and forth between your existing component and the new composed one, you can just use the props on the ab component (seeing as it's a 3rd party component in your case, I imagine it has a pretty well defined API). If you need to access the methods from the base class, you can use refs, as described in this answer.

Composition is a really powerful pattern - one of the main ways I use it in my apps is by creating entirely stateless components for the UI, and then creating 'container' components that wrap around and connect them up to the data they need. This creates a really nice separation between the UI and the logic (Dan Abramov wrote about the concept here - he's about 10000x smarter than I am and I'd be terrible at React without some of the stuff he's posted).

Sign up to request clarification or add additional context in comments.

4 Comments

Don't forget class ab extends React.Component
Thanks for your answer, actually I'm facing with the issue that "ab" component is from a3rd package, so I could not modify the "ab". Is there any way to implement an ES6 wrapper class (eg: abWrapper) that has all function for "ab" component so that I just extend from that ES6 wrapper class?
@HungTran - I edited my answer with a quick rundown of composing components - this is probably a better approach than the one I originally posted, and will work with both ES6 and React classes :)
This is how I would do it if i were unable to edit the original :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.