@wordpress/data
Version:
Data module for WordPress.
71 lines (64 loc) • 2.09 kB
text/typescript
/**
* WordPress dependencies
*/
import { useMemo, useRef } from '@wordpress/element';
import { useIsomorphicLayoutEffect } from '@wordpress/compose';
/**
* Internal dependencies
*/
import useRegistry from '../registry-provider/use-registry';
import type { DataRegistry } from '../../types';
type DispatchMap = (
dispatch: DataRegistry[ 'dispatch' ],
registry: DataRegistry
) => Record< string, ( ...args: unknown[] ) => unknown >;
/**
* Custom react hook for returning aggregate dispatch actions using the provided
* dispatchMap.
*
* Currently this is an internal api only and is implemented by `withDispatch`
*
* @param dispatchMap Receives the `registry.dispatch` function as
* the first argument and the `registry` object
* as the second argument. Should return an
* object mapping props to functions.
* @param deps An array of dependencies for the hook.
* @return An object mapping props to functions created by the passed
* in dispatchMap.
*/
const useDispatchWithMap = (
dispatchMap: DispatchMap,
deps: unknown[]
): Record< string, ( ...args: unknown[] ) => unknown > => {
const registry = useRegistry();
const currentDispatchMapRef = useRef( dispatchMap );
useIsomorphicLayoutEffect( () => {
currentDispatchMapRef.current = dispatchMap;
} );
return useMemo( () => {
const currentDispatchProps = currentDispatchMapRef.current(
registry.dispatch,
registry
);
return Object.fromEntries(
Object.entries( currentDispatchProps ).map(
( [ propName, dispatcher ] ) => {
if ( typeof dispatcher !== 'function' ) {
// eslint-disable-next-line no-console
console.warn(
`Property ${ propName } returned from dispatchMap in useDispatchWithMap must be a function.`
);
}
return [
propName,
( ...args: unknown[] ) =>
currentDispatchMapRef
.current( registry.dispatch, registry )
[ propName ]( ...args ),
];
}
)
);
}, [ registry, ...deps ] );
};
export default useDispatchWithMap;