guac-hoc
GUAC-HOC
Overview
GUAC-HOC stands for General Usage Advanced Components (GUAC) - Higher Order Components (HOC). This library exposes a variety of compositional methods and components for the React library that allow for better and more consistent higher-order component and compositional behavior.Example Use Case
Say I have two higher-order components that apply styles to aWrappedComponent. How should I format
the classes to properly and consistently combine the props that the higher-order components may modify? Ultimately,
I want simple composition of components as down below without having to manually alter and append to props in
each higher-order component.WrappedComponent = higherOrderComponent1(higherOrderComponent2(WrappedComponent));
...
<WrappedComponent className='myClassName'/>
An example implementation is below. Notice the problem with className. Imagine that, as an end user, I define a
component, apply the higher order component, then want to pass in a className prop. This higher order component
would intercept it! Note that this is an issue with every prop, including event props such as onClick and onMouseDown.
While it is possible to solve this with composition from the library manager's end, this can lead to ugly code and excessive
boilerplate.
function higherOrderComponent1(WrappedComponent) {
...
return class WrapperComponent extends React.Component {
...
render() {
return (
/* className is intercepted and overridden, so some user-passed props
like className are not propagated to WrappedComponent*/
<WrappedComponent {...this.props} className='styleClass1'/>
);
}
}
}
So instead, we let this library handle it.
function higherOrderComponent(WrappedComponent) {
...
class WrapperComponent extends React.Component {
constructor() {
super();
//Instead of following ES6 experimental structure, use this to have more java-like declarative syntax.
this.bindAllMethods();
}
...
render() {
return (
/* \/ Call this to retrieve the composed classNames.*/
<WrappedComponent {...this.props} className={this.className()}/>
);
}
//This line provides higher-order-component functionality to your components.
return HOC(WrapperComponent);
}
}
Installation
Run the following to install:
npm install --save guac-hoc@latest
Usage
Importing
import HOC from 'guac-hoc/lib/HOC';
import Guac from 'guac-hoc/lib/Guac';
Exposed Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
this.bindAllMethods() |
None | None | Use in constructor. Binds all class methods to the instance. |
this.deleteUsedProps(propNames) |
propNames: list<string> | props: object | Removes all props that you do not want exposed to your WrappedComponent. |
Compositional Methods
These methods are special, reserved methods that each map to a prop. If your higher-order component intercepts or passes
down any of these props to the WrappedComponent, instead implement the corresponding method and pass it or its return value
down instead.
| Method | Parameters | Returns | Description |
|---|---|---|---|
this.className() |
None | string | Define the calculation for your higher-order component's className here and return it. Call this in render() to get the composed className and pass that value down. |
this.onClick(event) |
event | None | Define onClick prop. Pass prop as a method reference as usual. |
this.onMouseDown(event) |
event | None | Define onMouseDown prop. Pass prop as a method reference as usual. |
this.onMouseUp(event) |
event | None | Define onMouseUp prop. Pass prop as a method reference as usual. |
this.onMouseEnter(event) |
event | None | Define onMouseEnter prop. Pass prop as a method reference as usual. |
this.onMouseLeave(event) |
event | None | Define onMouseLeave prop. Pass prop as a method reference as usual. |