Используйте унаследованные функции из класса в функциональных компонентах - PullRequest
0 голосов
/ 05 марта 2020

В моем текущем корпоративном коде есть концепция базовых классов и функций Specifi c компоненты

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

А затем у нас есть определенные c классы, такие как PetrolEngine и 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()
      }
 }

Теперь я хочу создать новый компонент, такой как ElectricEngine. Есть ли способ написать это как функциональный компонент, не затрагивая существующие компоненты на основе классов.

И да, я знаю, что Композиция должна была быть лучшим подходом, а не наследованием здесь. Но это то, что есть.

1 Ответ

1 голос
/ 05 марта 2020

Это определенно возможно, поскольку классы являются просто синтаксическим сахаром по сравнению с существующим наследованием на основе прототипов.

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) эквивалентно ElectricEngine extends Engine, а ElectricEngine.prototype.render позволит вам переопределить метод render компонента Engine, чтобы вы может визуализировать ElectricEngine -specifi c JSX.

Однако на самом деле это не совсем правильно и выглядит не очень хорошо, и, как вы сказали, композиция будет лучшим подходом.

Я бы, вероятно, остановился на class-based components, если вы хотите расширить некоторые функциональные возможности родительских компонентов, поскольку с ними гораздо проще работать в вашем конкретном c случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...