Абстракция в React.js

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

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 - в этом случае class - никогда не изменятся.

Это анти-шаблон в реактиве? Или это нормально?

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

Ответ 1

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

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 применять больше оптимизаций, так как вашим компонентам не требуется специальная поддержка событий или управление состоянием. Это еще проще рассуждать, поскольку теперь вы просто работаете с чистыми функциями.

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