React component inheritance

17,147

If you want to use the parent's method inside children, you need to extend parent and call super in the constructor. super will run the constructor of the parent component. So, when you define or reference your method in the parent's constructor it can be accessible.

class A extends React.Component{
  constructor(props) {
    super(props)
    this.parentMethod = this.parentMethod.bind(this) //referencing the method in constructor
  }
  
  parentMethod(){
    console.log('Parent Method')
  }
  
  render(){
    return false
  }
}

class B extends A{
  constructor(){
    super() //call super to run parent's constructor
  }
  
  render(){
    this.parentMethod() //calling parent method
    return false
  }
}

ReactDOM.render(
  <div>
    <A/>
    <B/>
  </div>,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Hope this helps!

Share:
17,147
Denis Rybalka
Author by

Denis Rybalka

I have a passion for software architecture and engineering effective solutions.

Updated on June 18, 2022

Comments

  • Denis Rybalka
    Denis Rybalka almost 2 years

    Base component

    import React, { Component, PropTypes } from 'react';
    import { Link } from 'react-router';
    import { connect } from 'react-redux';
    import { addToCart, removeFromCart, changeQuantity } from '../../actions/CartActions';
    
    @connect(null, { addToCart, removeFromCart, changeQuantity })
    class Product extends Component {
      constructor() {
        super();
        this.addToCart = this.addToCart.bind(this);
      }
      addToCart() {
        this.props.addToCart(this.props.product);
      }
      removeFromCart() {
    
        this.props.removeFromCart(this.props.product);
      }
      changeProductQuantity() {
    
        this.props.changeQuantity(this.props.product);
      }
      render() {
        return (
          <div className="product_box">
            <h3>{this.props.product.title}</h3>
            <Link to={`details/${this.props.product._id}`}>
              <img src={this.props.product.image_url} alt={this.props.product.title} />
            </Link>
            <p>{this.props.product.description}</p>
            <p className="product_price">{this.props.product.price} {this.props.product.currency}</p>
            <Link onClick={this.addToCart} className="addtocart" />
            <Link to={`details/${this.props.product._id}`} className="detail" />
          </div>
        );
      }
    }
    
    Product.propTypes = {
      product: PropTypes.shape({
        _id: PropTypes.string,
        title: PropTypes.string,
        description: PropTypes.string,
        image_url: PropTypes.string,
        price: PropTypes.string,
        currency: PropTypes.string,
      }),
      addToCart: PropTypes.func,
      removeFromCart: PropTypes.func,
      changeQuantity: PropTypes.func,
    };
    
    export default Product;
    

    Child component

    import React from 'react';
    import Product from '../common/Product';
    
    class InlineProduct extends Product {
      render() {
        const { product } = this.props;
        return (
          <tr>
            <td>
              <img src={product.image_url} alt={product.title} />
            </td>
            <td>{product.title}</td>
            <td className="align-center">
              <input className="quantity-input" type="text" value="1" onChange={this.changeProductQuantity} />
            </td>
            <td className="align-right">{product.price} {product.currency}</td>
            <td className="align-right">{product.price} {product.currency}</td>
            <td className="align-center">
              <a onChange={this.removeFromCart}>
                <img src="images/remove_x.gif" alt="remove" /><br />Remove
              </a>
            </td>
          </tr>
        );
      }
    }
    
    export default InlineProduct;
    

    It's looks like second component can't inherit methods from first one. I can call parent's methods from child component. Any ideas? I think props validation is ok because it's static, but need some solution to make methods reachable form child component.