React: Passing props via super(props) when extending another component not working

Created on 7 Sep 2015  路  6Comments  路  Source: facebook/react

_I'm not sure if this is a real issue or not but the behavior was unexpected for me. React version: 0.13.3_

I have two components, _Shape_ and _Circle_. _Shape_ is a general concept and _Circle_ is just a special case of _Shape_. I'm using ES6 class syntax to define the components. I'm trying to override _Shape's_ defaultProps by passing props from _Circle's_ constructor using super(props). This isn't working.

See the following code(or JSBin):

import React from 'react';

class Shape extends React.Component {
    constructor(props) {
        // At this point, props.shapeType === 'Circle', when Circle component
        // Is used
        super(props);
    }

    render() {
        // At this point this.props.shapeType is still null,
        // I expected it to equal 'Circle'
        console.log(this.props);

        return <div>{this.props.shapeType}</div>;
    }
}
Shape.defaultProps = {
    shapeType: null
};

class Circle extends Shape {
    constructor(props) {
        let propsCopy =  Object.assign({}, props);
        propsCopy.shapeType = 'Circle'
        super(propsCopy);
    }
}

React.render(
    <Circle />,
    document.querySelector('body')
);

Most helpful comment

Do not use inheritance to build React components. Try:

class Circle extends React.Component {
    render() {
        return <Shape {...this.props} shapeType="Circle" />;
    }
}

All 6 comments

To make the code working as intended, _Circle_ should be defined this way:

class Circle extends Shape {}
Circle.defaultProps = {
    shapeType: 'Circle'
};

Is this intended or should the code originally pasted work too?

Do not use inheritance to build React components. Try:

class Circle extends React.Component {
    render() {
        return <Shape {...this.props} shapeType="Circle" />;
    }
}

For others that end up here trying to solve the same problem, and to extend on spicyjs answer not to use inheritance, here is some rationale about composition and inheritance in react: https://facebook.github.io/react/docs/composition-vs-inheritance.html

For me the this was caused by defining default class props as:

class Foobar extends Component {
  // Wrong
  props = {
    foo: 'bar'
  }

  // Correct
  static defaultProps = {
    foo: 'bar'
  }
}

Hey, this can as well be done like this

Human.js

import React, { Component } from 'react';

class Human extends Component {

    constructor(props) {
        super(props);
        this.state = {
            name: "Sunny"
        }
    }

    render() {
        return (
            <div>
                <ThirdPerson />
                <div>
                    I am a Human!
                </div>
                <div>My name is {this.state.name}!</div>
            </div>
        );
    }
}

class ThirdPerson extends Component {
    render() {
        return (
            <div>
                <div>
                    I am a Third Person!
                </div>
            </div>
        );
    }
}

export default Human;

Person.js

import React from 'react';
import Human from './human';

class Person extends Human {
    render() {
        return (
            <div>
                <Human />
                <div>
                    I am a Person!
                </div>
                <div>My name is {this.state.name}!</div>
            </div>
        );
    }
}

export default Person;

Please let me know if I have misunderstood the concept!

Thanks :)

P.S.: Please ignore the way I am naming!

Our recommendation is to not use inheritance for React components.
https://reactjs.org/docs/composition-vs-inheritance.html

There are many pitfalls, and if you disagree with this recommendation, you鈥檙e mostly on your own.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kib357 picture kib357  路  103Comments

acdlite picture acdlite  路  83Comments

sophiebits picture sophiebits  路  107Comments

addyosmani picture addyosmani  路  143Comments

gaearon picture gaearon  路  133Comments