Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React component inheritance

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.

like image 274
Denis Rybalka Avatar asked Oct 30 '16 13:10

Denis Rybalka


People also ask

Can you do components inheritance in React?

Inheritance allows the app to do the coupling between the parent-child component and reuse properties such as state values and function in its child components. React does not use inheritance except in the initial component class, which extends from the react package.

Why composition is better than inheritance in React?

React team suggests using Composition over Inheritance. React treats everything as a component and follows a strong component-based model. This is one of the main reasons why composition is a superior technique for code reuse than inheritance.

Can you pass React component as prop?

You can pass a component as props in React by using the built-in children prop. All elements you pass between the opening and closing tags of a component get assigned to the children prop. Copied!


Video Answer


1 Answers

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!

like image 105
Pranesh Ravi Avatar answered Sep 23 '22 12:09

Pranesh Ravi