Orboo
Orboo

Reputation: 83

Extend React Component using Flow

I try to extend React.Component using Flow. The idea is quite simple,

Bar extends Foo.

Foo extends React.component.

Basically, i just want to share default properties and add one into the subclass. Then something like that:

/* @flow */
import React from 'react';
import Foo from './Foo.js';

class Bar extends Foo {

    props : {
        prop2 : string
    }
    
    static defaultProps = {
        prop1: "Default Bar",
        prop2: "Hello World"
    }

    render() {

    }
}
export default Bar;
/* @flow */
import React from 'react';
class Foo extends React.Component {

    props : {
        prop1 : string
    }
    
    static defaultProps = {
        prop1: "Default Foo"
    }

    render() {
        return;
    }
}

export default Foo;

Of course, this code do not work at all, but do you have any idea and sample code ?

Many thanks,

Orb

Upvotes: 1

Views: 1082

Answers (1)

thinhvo0108
thinhvo0108

Reputation: 2232

Actually, as found on their official documents, React's creators recommend using composition over inheritance:

https://facebook.github.io/react/docs/composition-vs-inheritance.html

I also heard about some cases that several developers switched road in the middle of the project when they chose using inheritance at first, and as stated React's people, you may re-think about it:

At Facebook, we use React in thousands of components, and we haven't found any use cases where we would recommend creating component inheritance hierarchies.

(...found here):

https://facebook.github.io/react/docs/composition-vs-inheritance.html#so-what-about-inheritance

=========

ADDED EXAMPLE FOR COMPOSITION:

However, my below composition pattern example may help you achieve what you want (kind of "inheritance-like"):

Foo.js (just add getDefaultProperty())

/* @flow */
import React from 'react';
class Foo extends React.Component {

    props : {
        prop1 : string
    }

    static defaultProps = {
        prop1: "Default Foo"
    }

    getDefaultProperty = () => {
      return this.prop1;
    }

    render() {
        return;
    }
}

export default Foo; 

Bar.js (this partially extends "Foo" using composition pattern):

/* @flow */
import React from 'react';
import Foo from './Foo.js';

class Bar extends React.Component {

    props : {
        prop2 : string
    }

    static defaultProps = {
        prop1: "Default Bar",
        prop2: "Hello World"
    }

    componentDidMount() {
      console.log(this.refs.parent.getDefaultProperty());
      // here you should see prop1 of Foo (the parent) is logged
      // or you can copy prop1 value from parent:
      if (this.refs.parent && this.refs.parent.getDefaultProperty()){
        this.prop1 = this.refs.parent.getDefaultProperty();
      }           

    }

    render() {
      return (
        <Foo ref="parent">
          <div>{this.prop2 + ", I am the Bar component, my value now is " + this.prop1}</div>
        </Foo>
      )        
   }
}
export default Bar;

In more details, the Bar component still extends React.Component, but it can still access the Foo's method, which returns Foo's prop1 by using ref

Actually, just render Foo in the render method of Bar, give it a ref then we can access component Foo's method. This is composition pattern.

Upvotes: 2

Related Questions