Add reusing functionality to existing component classes
function HOC(WrappedComponent) {
// abstract logic
return <WrappedComponent enhanced={true} />;
}
const EnhancedComponent = HOC(WrappedComponent);
function HOC(WrappedComponent) {
// returns another component
return class extends React.Component {
// constructor or lifecycle methods...
render() {
// ... and renders the wrapped component with the fresh data!
// Notice that we pass through any additional props
return <WrappedComponent data={this.state.data}
{...this.props} />;
}
}
}
const EnhancedComponent = HOC(WrappedComponent);
function HOC(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
return super.render()
}
}
}
const EnhancedComponent = HOC(WrappedComponent);
const EnhancedComp = connect(mapStateToProps)(MyComp);
HOC(MyComp);
Curry
/* HOC */
export default WrappedComponent => class Optimistic extends Component {
state = {
isActive: this.props.isActive
}
handleOnPress = async () => {
// optimistic update
const originStatus = this.state.isActive;
this.setState({ isActive: !originStatus });
// do fetch
let isSuccess;
if (this.state.isActive) {
isSuccess = await this.props.inactivate();
} else {
isSuccess = await this.props.activate();
}
if (!isSuccess) {
this.setState({ isActive: originStatus });
}
}
render() {
return <WrappedComponent
{...this.props}
isActive={this.state.isActive}
onPress={this.handleOnPress} />;
}
};
/* Usage */
const OptimisticLikeBtn = Optimistic(LikeButton);
export default class LikeButton extends Component {
like = async () => {
const response = await likeRequest;
return response.isSuccess;
}
unlike = async () => {
const response = await unlikeRequest;
return response.isSuccess;
}
render() {
return (
<OptimisticLikeBtn
{...this.props}
isActive={this.props.isCollected}
activate={this.like}
inactivate={this.unlike} />
);
}
}