Created
February 13, 2020 19:58
-
-
Save samsch/f6de57126e19f73eb0ac771d4bc43ebf to your computer and use it in GitHub Desktop.
React Router Switch re-implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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