2015-05-15 2 views
15

Я в настоящее время наследование ES6 Реагировать базовый компонент следующим образом:Реагировать наследование компонентов ES6: работает, но не рекомендуется?

model.js (базовый компонент):

class ModelComponent extends React.Component { 

    render() { 
     // Re-used rendering function (in our case, using react-three's ReactTHREE.Mesh) 
     ... 
    } 

} 

ModelComponent.propTypes = { 
    // Re-used propTypes 
    ... 
}; 

export default ModelComponent; 

Тогда у меня есть две простирающиеся компоненты, как выглядят в основном так:

import ModelComponent from './model'; 

class RobotRetroComponent extends ModelComponent { 

    constructor(props) { 

     super(props); 

     this.displayName = 'Retro Robot'; 

     // Load model here and set geometry & material 
     ... 

    } 

} 

export default RobotRetroComponent; 

(Full source code here)

Это, кажется, работает нормально. Обе модели появляются и работают, как я ожидал.

Тем не менее, я читал в нескольких местах, что наследование не является правильным подходом с React - вместо этого я должен использовать композицию. Но опять же, Mixins не поддерживаются в React v0.13?

Итак, это подход, который я принимаю выше ОК? Если нет, то в чем проблема, и как мне это сделать?

+0

Mixins поддерживаются в React v0.13, только не при использовании классов ES6. Вы можете использовать формат React.createClass ({mixins: []}) для микширования. – Crob

+0

Спасибо @Crob. Было бы лучше, чем использовать наследование класса ES6? Вышеприведенное кажется мне проще ...? – poshaughnessy

+0

Если единственной повторно используемой частью вашего компонента является функция 'render' и ее' propTypes', почему примечание содержит ваши компоненты, составляющие ее в своих методах рендеринга? В реактиве композиция предпочтительнее над наследованием. –

ответ

31

Команда Facebook рекомендует использовать «идиоматические концепции JavaScript» при написании кода React, а поскольку для классов ES6 нет поддержки mixin, нужно просто использовать композицию (поскольку вы просто используете идиоматические функции Javascript).

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

export default function composeModal(Component){ 

    class Modal extends React.Component { 

     constructor(props){ 
      super(props) 
      this.state = {/* inital state */} 
     } 

     render() { 
      // here you can pass down whatever you want 'inherited' by the child 
      return <Component {...this.props} {..this.state}/> 
     } 

    } 

    Modal.propTypes = { 
     // Re-used propTypes 
     ... 
    }; 

    return Modal 
} 

Затем вы можете использовать функцию композиции следующим образом:

import composeModal from './composeModal'; 

class RobotRetroComponent extends React.Component { 

    constructor(props) { 
     super(props); 
     this.displayName = 'Retro Robot'; 
     // Load model here and set geometry & material 
     ... 
    } 

    render(){ 
     return /* Your JSX here */ 
    } 
} 

export default composeModal(RobotRetroComponent); 
+0

Спасибо. Я также хочу повторно использовать конструктор для загрузки моделей ... Мне все еще интересно, может ли в некоторых случаях быть просто прагматичным и использовать наследование, если это имеет смысл. В конце концов, мантра была только когда-либо «одобряла» композицию над наследством? (http://www.thoughtworks.com/insights/blog/composition-vs-inheritance-how-choose) Я собираюсь отметить это как принятое, хотя, потому что это помогло мне продумать его, и я считаю, что это поможет я решаю решение. Для других зрителей вам может потребоваться изменить «Modal» и «ModelComponent» на «Model», чтобы избежать путаницы :) – poshaughnessy

+1

Я понимаю, что вы говорите, и на первый взгляд кажется, что наследование не будет быть неправильным подходом как таковым. Однако команда React продолжает повторять, что библиотека в глубине души является «функциональной» библиотекой, поэтому я полагаю, что композиция будет более согласована с этим функциональным подходом. Также следует иметь в виду, что способ создания компонентов с использованием объектно-ориентированных шаблонов может быть устаревшим в будущем в пользу более функционального стиля, см. Https://github.com/reactjs/react-future/ –

+0

@poshaughnessy любой шанс у вас была последняя демо-версия? Я после точного решения вы предлагаете, но я все еще считаю, что приведенный выше код запутан, возможно, потому, что имена/демонстрации не ясны. Любая помощь будет фантастической! – sidonaldson

Смежные вопросы