ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
86 lines • 3.24 kB
JavaScript
import * as React from 'react';
import { useContext, useEffect, useRef } from 'react';
import { useNavigate as useReactRouterNavigate, useLocation, useParams, useBlocker, useMatch, useInRouterContext, Link, Navigate, Route, Routes, Outlet, matchPath, createHashRouter, RouterProvider as ReactRouterProvider, UNSAFE_DataRouterContext, UNSAFE_DataRouterStateContext, } from 'react-router-dom';
const routerProviderFuture = { v7_startTransition: false, v7_relativeSplatPath: false };
/**
* Hook to check if navigation blocking is supported.
* In react-router, blocking requires a data router.
*/
const useCanBlock = () => {
const dataRouterContext = useContext(UNSAFE_DataRouterContext);
const dataRouterStateContext = useContext(UNSAFE_DataRouterStateContext);
return !!(dataRouterContext && dataRouterStateContext);
};
/**
* Wrapper around react-router's useNavigate that returns a stable function reference.
*
* react-router's useNavigate forces rerenders on every navigation, even if we don't use the result.
* @see https://github.com/remix-run/react-router/issues/7634
*
* This wrapper uses a ref to return a stable function reference, avoiding unnecessary rerenders
* in components that use navigate but don't need to rerender on navigation.
*/
const useNavigate = () => {
const navigate = useReactRouterNavigate();
const navigateRef = useRef(navigate);
useEffect(() => {
navigateRef.current = navigate;
}, [navigate]);
// Return a stable function that always calls the latest navigate
return React.useCallback((...args) => {
return navigateRef.current(...args);
}, []);
};
/**
* Internal router component that creates a HashRouter.
* Only used when not already inside a router context.
*/
const InternalRouter = ({ children, basename, }) => {
const router = createHashRouter([{ path: '*', element: React.createElement(React.Fragment, null, children) }], {
basename,
future: {
v7_fetcherPersist: false,
v7_normalizeFormMethod: false,
v7_partialHydration: false,
v7_relativeSplatPath: false,
v7_skipActionErrorRevalidation: false,
},
});
return (React.createElement(ReactRouterProvider, { router: router, future: routerProviderFuture }));
};
/**
* RouterWrapper component for react-router.
* Creates a HashRouter if not already inside a router context.
*/
const RouterWrapper = ({ basename, children }) => {
const isInRouter = useInRouterContext();
if (isInRouter) {
return React.createElement(React.Fragment, null, children);
}
return React.createElement(InternalRouter, { basename: basename }, children);
};
/**
* Default router provider using react-router-dom.
* This provider is used by default when no custom routerProvider is provided to <Admin>.
*/
export const reactRouterProvider = {
// Hooks
useNavigate,
useLocation,
useParams: useParams,
useBlocker,
useMatch,
useInRouterContext,
useCanBlock,
// Components
Link,
Navigate,
Route,
Routes,
Outlet,
// Router creation
RouterWrapper,
// Utilities
matchPath,
};
//# sourceMappingURL=reactRouterProvider.js.map