Varun G
Varun G

Reputation: 44

Use inherticed functions from a class in functional components

My current enterprise code has the concept of Base classes and Function Specific components

class Engine extends Component {
   render(){
       this.renderEngine();
   }
}

And then we have specific classes such as PetrolEngine and DieselEngine

class PetrolEngine extends Engine {
      makeLessSound(){
        console.log('Silence');
      }
      consumeMoreFuel(){
         console.log('Gobble up!')
      }
      renderEngine(){
        this.makeLessSound();
        this.consumeMoreFuel()
      }
 }
class DieselEngine extends Engine {
      makeMoreSound(){
        console.log('Grrr!');
      }
      consumeLessFuel(){
         console.log('Dieting!')
      }
      renderEngine(){
        this.makeMoreSound();
        this.consumeLessFuel()
      }
 }

Now I want to create a new component like ElectricEngine. Is there a way to write this as a functional component without affecting the existing class based components.

And yes I am aware that Composition should have been the better approach instead of inheritance here. But it is what it is.

Upvotes: 0

Views: 47

Answers (1)

goto
goto

Reputation: 4425

This is definitely possible as classes are just a syntactical sugar over existing prototype-based inheritance.

class Engine extends React.Component {
  renderEngine = () => {
    return null;
  };
  render() {
    return this.renderEngine();
  }
}

function ElectricEngine() {}
ElectricEngine.prototype = new Engine();
ElectricEngine.prototype.constructor = Engine;
ElectricEngine.prototype.makeLessSound = function() {
  return <p>Making less sound!</p>;
};
ElectricEngine.prototype.consumeMoreFuel = function() {
  return <p>Consuming less fuel</p>;
};
ElectricEngine.prototype.renderEngine = function() {
  return (
    <div>
      <h3>ElectricEngine</h3>
      {this.makeLessSound()}
      {this.consumeMoreFuel()}
    </div>
  );
};

ReactDOM.render(
  <ElectricEngine />,
  document.getElementById("app")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

ElectricEngine.prototype = Object.create(Engine.prototype) is equivalent to ElectricEngine extends Engine and ElectricEngine.prototype.render will allow you to override the render method of the Engine component so that you can render ElectricEngine-specific JSX.

However, this doesn't really feel right and it doesn't look too good, and as you said, composition would be a better approach here.

I'd probably just stick to class-based components if you want to extend some functionality from parent components as it's much easier to work with them in your specific case.

Upvotes: 1

Related Questions