Расширение Реагирует.компоненты js



одна из вещей, которые я ценю больше всего о позвоночнике.js - это то, как простое и элегантное наследование работает. Я начинаю разбираться с React, и не могу найти ничего в react, что напоминает этот основной код



var Vehicle = Backbone.View.extend({
methodA: function() { // ... }
methodB: function() { // ... }
methodC: function() { // ... }
});

var Airplane = Vehicle.extend({
methodC: function() {
// Overwrite methodC from super
}
});


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



var vehicleMethods = {
methodA: function() { // ... }
methodB: function() { // ... }
}

var Vehicle = React.createClass({
mixins: [vehicleMethods]
methodC: function() {
// Define method C for vehicle
}
});

var Airplane = React.createClass({
mixins: [vehicleMethods]
methodC: function() {
// Define method C again for airplane
}
});


Это менее повторяется, чем определение одного и того же материала снова и снова, но это кажется, что он не так гибок, как магистральный путь. Например, я получаю ошибку, если я пытаюсь изменить/перезаписать метод, который существует в одном из моих миксины. Вдобавок ко всему, реакция.js way-это больше кода для меня, чтобы написать.



в react есть некоторые невероятно умные вещи, и похоже, что это больше похоже на то, что я не знаю, как правильно это сделать, чем на то, что функция отсутствует в React.



любые указатели очень ценятся.

583   4  

4 ответов:

чтобы получить что-то, что напоминает наследование (на самом деле состав как указано в комментариях), вы можете сделать Airplane в вашем примере оберните себя в Vehicle. Если вы хотите выставить методы на Vehicle на Airplane компонент, вы можете использовать ref и соедините их по одному. Это не совсем наследование (это на самом деле состав), особенно потому что this.refs.vehicle не будет доступен до тех пор, пока компонент не будет установленный.

var Vehicle = React.createClass({
    ...
});

var Airplane = React.createClass({
    methodA: function() {
      if (this.refs != null) return this.refs.vehicle.methodA();
    },
    ...
    render: function() {
        return (
            <Vehicle ref="vehicle">
                <h1>J/K I'm an airplane</h1>
            </Vehicle>
        );
    }
});

также стоит упомянуть, что в реагировать официальная документация они предпочитают композицию наследованию:

Так Что Насчет Наследства? В Facebook Мы используем React в тысячах компоненты, и мы не нашли никаких случаев использования, где мы бы рекомендуется создавать иерархии наследования компонентов.

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

если вы хотите повторно использовать функциональность без пользовательского интерфейса между компонентами, мы предложите извлечь его в отдельный модуль JavaScript. Этот компоненты могут импортировать и использовать эту функцию, объект или класс, не расширяя его.

еще одна вещь стоит упомянуть, что с помощью ES2015 / ES6+ вы также можете распространение реквизита объекта от Airplane компонент Vehicle компонент

render: function() {
    return (
        <Vehicle {...this.props}>
            <h1>J/K I'm an airplane</h1>
        </Vehicle>
    );
}

используя ReactOO, вы можете легко использовать наследование (отказ от ответственности: Я автор книги ReactOO):

(function () {

    // Class definitions. ReactOO requires class definition first just like you did in an OO way.

    window.Vehicle = window.ReactOO.ReactBase.extend({
        getReactDisplayName: function () {
            return 'Vehicle';
        },

        onReactRender: function (reactInstance) {
            var self = this;

            var text = self.methodC();

            return React.createElement('div', {}, text);
        },

        methodA: function () {
            console.log('Vehicle method A');
        },

        methodB: function () {
            console.log('Vehicle method B');
        },

        methodC: function () {
            return 'Vehicle method C';
        }
    });

    window.Airplane = window.Vehicle.extend({
        getReactDisplayName: function () {
            return 'Airplane';
        },

        methodC: function () {
            // Call this._super() to execute parent method.
            //this._super();
            return 'Airplane method C';
        }
    });

    var vehicle = new window.Vehicle();
    vehicle.render({}, '#vehicle');

    var airPlane = new window.Airplane();
    airPlane.render({}, '#airPlane');
})();
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>ReactOO Vehicle-Aireplane Example</title>
    <link rel="stylesheet" href="css/base.css" />
    <script src="scripts/react.js"></script>
    <script src="scripts/react-dom.js"></script>
    <script src="../src/reactoo.js"></script>
</head>
<body>
    <div id="vehicle">
    </div>
    <div id="airPlane">
    </div>
    <script src="scripts/vehicleAirplane.js">
    </script>
</body>
</html>
enter image description here

Если вы используете пакет webpack + babel+react NPM, настроенный в вашем проекте, то в реализации ES6 OOP это должно быть так просто:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class BaseComponentClass extends Component {
  componentDidMount() {} 
  render() { return (<div>Base Component</div>) }
}
class InheritedComponentClass extends BaseComponentClass {
  // componentDidMount is inherited
  render() { return (<div>Inherited Component</div>) } // render is overridden 
}
ReactDOM.render(<InheritedComponentClass></InheritedComponentClass>, 
     document.getElementById('InheritedComponentClassHolder'));

Примечание: вот простой стартовый комплект с такой настройкой:https://github.com/alicoding/react-webpack-babel

Я думаю, что расширение может быть сделано с помощью jQuery.extend или подобное

базы.jsx

module.exports = {
    methodA:function(){
        ...
    }
}

ребенок.jsx

var Base = require('./Base.jsx');

module.exports = React.createClass($.extend({},Base,{
    methodB:function(){
        ...
        this.methodA();
        ...
    },
    render:function(){
        return ...
    }
}));

Comments

    Ничего не найдено.