2015-11-24 2 views
10

Я хочу использовать некоторую абстракцию при создании моих компонентов React. Например:Абстракция в React.js

class AbstractButton extends React.Component { 
    render() { 
    return (
     <button 
     onClick={this.props.onClick} 
     className={this.definitions.className}> 
     {this.props.text} 
     </button> 
    } 
} 
class PrimaryButton extends AbstractButton { 
    constructor(options) { 
    super(options); 
    this.definitions = { 
     className: 'btn btn-primary' 
    }; 
    } 
} 
class SuccessButton extends AbstractButton { 
    constructor(options) { 
    super(options); 
    this.definitions = { 
     className: 'btn btn-success' 
    }; 
    } 
} 

Я не хочу, чтобы передать эти definitions через props, потому что я знаю, что эти definitions --in этот случай class не --будут не изменятся.

Является ли это анти-узором в реактиве? Или все в порядке?

Мой вопрос относится к this altjs issue: этот вид абстракции несовместим с @connectToStores.

+2

Реакция имеет тенденцию сосредотачиваться на композиции, а не наследовании, но ваш код не выглядит злым для меня. – christopher

+3

Да, это вообще считается анти-шаблон. Вот интересная статья об этом: https://medium.com/@dan_abramov/how-to-use-classes-and-sleep-at-night-9af8de78ccb4 –

ответ

10

Вообще говоря, нет никаких причин, чтобы не использовать состав здесь вместо глубокого наследования:

class Button extends React.Component { 
    render() { 
    return (<button 
      onClick={this.props.onClick} 
      className={this.props.className} 
      > 
      {this.props.text} 
      </button>); 
    } 
    static propTypes = { 
     className: React.PropTypes.string.isRequired, 
     onClick: React.PropTypes.func 
    } 
} 

class PrimaryButton extends React.Component { 
    render() { 
    return <Button {...this.props} className="btn btn-primary" />; 
    } 
} 

Это так же, как функциональные, как то, что вы предлагаете, но гораздо проще и легче рассуждать о. Он очень четко показывает, какая информация вам нужна Button.

После того, как вы сделаете этот шаг, вы можете устранить классы вообще и использовать апатриды компоненты:

const Button = (props) => (<button 
      onClick={props.onClick} 
      className={props.className} 
      > 
      {props.text} 
      </button>); 
Button.propTypes = { 
     className: React.PropTypes.string.isRequired, 
     onClick: React.PropTypes.func 
}; 

const PrimaryButton = (props) => 
    <Button {...props} className="btn btn-primary" />; 

const SuccessButton = (props) => 
    <Button {...props} className="btn btn-success" />; 

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

В стороне, если вы пытаетесь создать некоторые компоненты React, которые обертывают Bootstrap, тогда, возможно, вам стоит взглянуть на React-Bootstrap.

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