React Routing in Plain React
React Routing in 50 Lines of Code
React Router is one of the most popular React libraries, as it serves as a bridge between React’s SPA philosophy and more traditional multi page websites where links are used for navigation.
I personally found React Router a bit cumbersome to use. In addition, I generally don’t like having too many dependencies in my project. Fortunately, after searching a bit online, creating my own react router in plain react proved to be relatively straightforward.
Credits to the following from where I learnt some of the necessary concepts:
- https://chrismorgan.info/about/
- https://ncoughlin.com/posts/react-navigation-without-react-router/
- https://dilshankelsen.com/react-routing-without-react-router/
Without further ado…here is the code :) Star the repo if you like it (the repo also contains some useful comments and is better formatted than below).
import React from 'react';
import { useEffect, useState } from 'react';
window.addEventListener("click", function (event) {
const link = event.target.closest("a");
if (
!event.button &&
!event.altKey &&
!event.ctrlKey &&
!event.metaKey &&
!event.shiftKey &&
link &&
link.href.startsWith(window.location.origin + "/") &&
link.target !== "_blank"
) {
event.preventDefault();
navigate(link.href);
}
});
export default function Router ({routes, defaultComponent}) {
const [currentPath, setCurrentPath] = useState(window.location.pathname);
useEffect(() => {
const onLocationChange = () => {
setCurrentPath(window.location.pathname);
}
window.addEventListener('popstate', onLocationChange);
return () => {
window.removeEventListener('popstate', onLocationChange)
};
}, [])
return routes.find(({path, component}) => path === currentPath)?.component || defaultComponent
}
export function navigate (href) {
// update url
window.history.pushState({}, "", href);
// communicate to Routes that URL has changed
const navEvent = new PopStateEvent('popstate');
window.dispatchEvent(navEvent);
}