hooks_use-route-handler.js
import { React, ReactRouter } from '@gravityforms/libraries';
const { useEffect, useRef } = React;
const { useSearchParams } = ReactRouter;
/**
* @module useRouteHandler
* @description A hook that handles route changes.
*
* @since 4.2.0
*
* @param {object} args The arguments for the hook.
* @param {Function} args.handler The handler function to run when the route changes.
*
* @return {object} The route handler state and actions.
*/
const useRouteHandler = ( { handler } = {} ) => {
const [ searchParams, setSearchParams ] = useSearchParams();
const prevSearchParams = useRef( searchParams );
const runIdRef = useRef( 0 );
const handlerRef = useRef( handler );
handlerRef.current = handler;
useEffect( () => {
const fn = handlerRef.current;
if ( ! fn ) {
return;
}
const currentRunId = runIdRef.current + 1;
runIdRef.current = currentRunId;
const runHandler = async () => {
await fn( {
prevSearchParams: prevSearchParams.current,
searchParams,
setSearchParams,
} );
// Only the latest invocation may update prevSearchParams so overlapping async handlers cannot reorder it.
if ( runIdRef.current === currentRunId ) {
prevSearchParams.current = searchParams;
}
};
try {
runHandler();
} catch ( error ) {
console.error( 'Error running route handler:', error );
}
}, [ searchParams, setSearchParams ] );
return {
searchParams,
setSearchParams,
};
};
export default useRouteHandler;