What is @wordpress/compose?
@wordpress/compose is a utility library for composing higher-order components (HOCs) in React. It provides a set of functions that help in managing component state, lifecycle, and other common patterns in a more declarative and functional way.
What are @wordpress/compose's main functionalities?
withState
The `withState` HOC is used to add state to a functional component. In this example, `count` is the state variable and `setCount` is the function to update it.
const { withState } = require('@wordpress/compose');
const MyComponent = ({ count, setCount }) => (
<div>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
const EnhancedComponent = withState('count', 'setCount', 0)(MyComponent);
withInstanceId
The `withInstanceId` HOC provides a unique instance ID to each instance of the component. This can be useful for accessibility or for differentiating between multiple instances of the same component.
const { withInstanceId } = require('@wordpress/compose');
const MyComponent = ({ instanceId }) => (
<div>
<p>Instance ID: {instanceId}</p>
</div>
);
const EnhancedComponent = withInstanceId(MyComponent);
compose
The `compose` function is used to combine multiple HOCs into a single HOC. In this example, `withState` and `withInstanceId` are combined to enhance `MyComponent`.
const { compose, withState, withInstanceId } = require('@wordpress/compose');
const MyComponent = ({ count, setCount, instanceId }) => (
<div>
<p>Instance ID: {instanceId}</p>
<p>{count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
const EnhancedComponent = compose(
withState('count', 'setCount', 0),
withInstanceId
)(MyComponent);
Other packages similar to @wordpress/compose
recompose
Recompose is a React utility belt for function components and higher-order components. It provides a similar set of utilities for managing state, lifecycle, and other common patterns in a more functional way. Compared to @wordpress/compose, Recompose offers a broader range of utilities and is more widely used in the React community.
redux
Redux is a state management library for JavaScript applications. While it is not specifically for composing higher-order components, it provides a way to manage application state in a predictable way. Compared to @wordpress/compose, Redux is more focused on global state management rather than enhancing individual components.
react-redux
React-Redux is the official React binding for Redux. It provides HOCs like `connect` to connect React components to the Redux store. Compared to @wordpress/compose, React-Redux is specifically designed for integrating Redux with React components.
Compose
The compose
package is a collection of handy Higher Order Components (HOCs) you can use to wrap your WordPress components and provide some basic features like: state, instance id, pure...
The compose
function is an alias to flowRight from Lodash. It comes from functional programming, and allows you to compose any number of functions. You might also think of this as layering functions; compose
will execute the last function first, then sequentially move back through the previous functions passing the result of each function upward.
An example that illustrates it for two functions:
const compose = ( f, g ) => x
=> f( g( x ) );
Here's a simplified example of compose in use from Gutenberg's PluginSidebar
component:
Using compose:
const applyWithSelect = withSelect( ( select, ownProps ) => {
return doSomething( select, ownProps);
} );
const applyWithDispatch = withDispatch( ( dispatch, ownProps ) => {
return doSomethingElse( dispatch, ownProps );
} );
export default compose(
withPluginContext,
applyWithSelect,
applyWithDispatch,
)( PluginSidebarMoreMenuItem );
Without compose
, the code would look like this:
const applyWithSelect = withSelect( ( select, ownProps ) => {
return doSomething( select, ownProps);
} );
const applyWithDispatch = withDispatch( ( dispatch, ownProps ) => {
return doSomethingElse( dispatch, ownProps );
} );
export default withPluginContext(
applyWithSelect(
applyWithDispatch(
PluginSidebarMoreMenuItem
)
)
);
Installation
Install the module
npm install @wordpress/compose --save
This package assumes that your code will run in an ES2015+ environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using core-js or @babel/polyfill will add support for these methods. Learn more about it in Babel docs.
API
For more details, you can refer to each Higher Order Component's README file. Available components are located here.
compose
src/index.js#L22-L22
Composes multiple higher-order components into a single higher-order component. Performs right-to-left function
composition, where each successive invocation is supplied the return value of the previous.
Parameters
- hocs
...Function
: The HOC functions to invoke.
Returns
Function
: Returns the new composite function.
createHigherOrderComponent
src/index.js#L6-L6
Given a function mapping a component to an enhanced component and modifier
name, returns the enhanced component augmented with a generated displayName.
Parameters
- mapComponentToEnhancedComponent
Function
: Function mapping component to enhanced component. - modifierName
string
: Seed name from which to generated display name.
Returns
WPComponent
: Component class with generated display name assigned.
ifCondition
src/index.js#L7-L7
Higher-order component creator, creating a new component which renders if
the given condition is satisfied or with the given optional prop name.
Parameters
- predicate
Function
: Function to test condition.
Returns
Function
: Higher-order component.
pure
src/index.js#L8-L8
Given a component returns the enhanced component augmented with a component
only rerendering when its props/state change
Parameters
- mapComponentToEnhancedComponent
Function
: Function mapping component to enhanced component. - modifierName
string
: Seed name from which to generated display name.
Returns
WPComponent
: Component class with generated display name assigned.
withGlobalEvents
src/index.js#L9-L9
Undocumented declaration.
withInstanceId
src/index.js#L10-L10
A Higher Order Component used to be provide a unique instance ID by
component.
Parameters
- WrappedComponent
WPElement
: The wrapped component.
Returns
Component
: Component with an instanceId prop.
withSafeTimeout
src/index.js#L11-L11
A higher-order component used to provide and manage delayed function calls
that ought to be bound to a component's lifecycle.
Parameters
- OriginalComponent
Component
: Component requiring setTimeout
Returns
Component
: Wrapped component.
withState
src/index.js#L12-L12
A Higher Order Component used to provide and manage internal component state
via props.
Parameters
- initialState
?Object
: Optional initial state of the component.
Returns
Component
: Wrapped component.