I want to use some abstraction in the creation of my React components. For example:
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'
};
}
}
I don't want to pass these definitions
via props
because I know that these definitions
--in this case the class
--will never change.
Is it an anti-pattern in React? Or is it OK?
My question refers to this altjs issue: this kind of abstraction isn't compatible with @connectToStores
.
Generally speaking, there's no reason not to use composition here instead of deep inheritance:
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" />;
}
}
This is just as functional as what you propose, but is a lot simpler and easier to reason about. It makes it very clear what information your Button
actually needs to do its work.
Once you make this leap, you can eliminate the classes altogether and use stateless components:
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" />;
This will allow React to apply more optimizations since your components do not need any special lifecycle event support or state management. It is also even easier to reason about since now you are just working with pure functions.
As an aside, if you are trying to make some React components that wrap Bootstrap, then perhaps you should take a look at React-Bootstrap.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With