Skip to content

Instantly share code, notes, and snippets.

@codebycarlos
Last active May 17, 2024 15:48
Show Gist options
  • Save codebycarlos/ee7700ae2904c25cc90a76448b8ad986 to your computer and use it in GitHub Desktop.
Save codebycarlos/ee7700ae2904c25cc90a76448b8ad986 to your computer and use it in GitHub Desktop.
connectRouter
import type { ReactElement, ComponentType } from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom";
export type Router = {
location: ReturnType<typeof useLocation>;
navigate: ReturnType<typeof useNavigate>;
params: ReturnType<typeof useParams>;
};
export type MapRouterToProps<InjectedProps = unknown> = (
router: Router
) => InjectedProps;
/**
* Code inspired from: https://reactrouter.com/en/v6.3.0/faq.
*
* Modified to add types and mapRouterToProps.
*
* Enables use of react-router-dom without hooks in a fashion similar to Redux's
* connect function.
*/
export function connectRouter<InjectedProps>(
mapRouterToProps: MapRouterToProps<InjectedProps>
) {
/* Similar to Redux's connect function, here we return a function which
* takes in the component to be connected and returns a component with
* the router props injected.
*/
return function <Props extends InjectedProps>(
Component: ComponentType<Props>
): (props: Omit<Props, keyof InjectedProps>) => ReactElement {
/* Higher order component which calls the router hooks and
* calls on mapRouterToProps in order to inject the router props.
*/
return function ComponentWithRouterProp(
// Injected props are no longer required to be passed in.
props: Omit<Props, keyof InjectedProps>
): ReactElement {
const location = useLocation();
const navigate = useNavigate();
const params = useParams();
return (
<Component
{...(props as Props)}
{...mapRouterToProps({ location, navigate, params })}
/>
);
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment