hooks_use-route-handler.js
import { React, ReactRouter } from '@gravityforms/libraries';
const { useEffect, useRef, useState } = React;
const { useSearchParams } = ReactRouter;
/**
* @module useRouteHandler
* @description A hook that handles route changes.
*
* @since 4.2.0
*
* @return {object} The route handler state and actions.
*/
const useRouteHandler = () => {
const [ routeHandlerIds, setRouteHandlerIds ] = useState( [] );
const [ routeHandlers, setRouteHandlers ] = useState( {} );
const [ searchParams, setSearchParams ] = useSearchParams();
const prevSearchParams = useRef( searchParams );
const isNavigating = useRef( false );
/**
* @function addRouteHandler
* @description Add a route handler.
*
* @since 4.2.0
*
* @param {string} id The id of the route handler.
* @param {Function} handler The handler function.
*
*/
const addRouteHandler = ( id, handler ) => {
if ( ! id || ! handler ) {
return;
}
if ( routeHandlerIds.includes( id ) ) {
return;
}
setRouteHandlers( {
...routeHandlers,
[ id ]: handler,
} );
setRouteHandlerIds( [ ...routeHandlerIds, id ] );
};
/**
* @function removeRouteHandler
* @description Remove a route handler.
*
* @since 4.2.0
*
* @param {string} id The id of the route handler.
*
*/
const removeRouteHandler = ( id ) => {
if ( ! id ) {
return;
}
setRouteHandlers( {
...routeHandlers,
[ id ]: undefined,
} );
setRouteHandlerIds( routeHandlerIds.filter( ( handlerId ) => handlerId !== id ) );
};
/**
* @function setRoute
* @description Set the route. Sets isNavigating to true to prevent the routeHandlers from running.
*
* @since 4.2.0
*
* @param {object} params The params to set.
* @param {object} options The options to set.
*
*/
const setRoute = ( params, options = {} ) => {
isNavigating.current = true;
setSearchParams( params, options );
};
useEffect( () => {
if ( isNavigating.current ) {
isNavigating.current = false;
return;
}
// Loop through all the route handlers and call them.
routeHandlerIds.forEach( ( id ) => {
const handler = routeHandlers[ id ];
if ( ! handler ) {
return;
}
handler( {
searchParams,
prevSearchParams: prevSearchParams.current,
} );
} );
prevSearchParams.current = searchParams;
}, [ searchParams ] );
return {
addRouteHandler,
removeRouteHandler,
setRoute,
searchParams,
setSearchParams,
};
};
export default useRouteHandler;