Skip to content

Instantly share code, notes, and snippets.

@samsch
Created February 13, 2020 19:58
Show Gist options
  • Save samsch/f6de57126e19f73eb0ac771d4bc43ebf to your computer and use it in GitHub Desktop.
Save samsch/f6de57126e19f73eb0ac771d4bc43ebf to your computer and use it in GitHub Desktop.
React Router Switch re-implementation
import React from 'react';
import {
BrowserRouter as Router,
Link,
} from 'react-router-dom';
import Switch from './Switch';
const MyRoute = ({ name }) => {
React.useEffect(() => {
console.log('Mounted');
return () => {
console.log('Unmounted');
};
}, []);
return <div>The route {name}</div>;
};
export default function App() {
return (
<Router>
<div>
<Link to="/1">C 1</Link>
<Link to="/1/4">C 2</Link>
</div>
<Switch>
{{
'exact /1': <MyRoute name="Number 1" />,
'/1/:position': match => (
<MyRoute name={`Number ${match.params.position}`} />
),
}}
</Switch>
</Router>
);
}
import React from 'react';
import {
BrowserRouter as Router,
matchPath,
useLocation,
} from 'react-router-dom';
const Switch = ({ children: routes }) => {
const route = useLocation().pathname;
let realMatch = null;
const current = Object.entries(routes).find(([path]) => {
const exact = /^exact /.test(path);
const match = matchPath(
route,
exact ? { exact: true, path: path.slice(6) } : { path }
);
if (match) {
realMatch = match;
return true;
}
return false;
});
if (current) {
const renderable = current[1];
if (typeof renderable === 'function') {
return renderable(realMatch);
}
return renderable;
}
return null;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment