How I built a simple react-navigation clone in 5 minutes

React navigation is a really powerful library. But you often don't need that much.
Building your library for this case teaches you a lot about React Context API and how simple the navigation in a SPA happens.
Integration
export function App() {
return (
<NavProvider>
<Router></Router>
</NavProvider>
)
}
Defining our routes
export function Router() {
const navContext = useContext(NavContext)
switch (navContext.current.path) {
case 'cockpit':
return <Cockpit />
default:
return (
<header>
<Navbar />
</header>
)
}
}
Under the hood?
export function NavProvider({ children, entryPath }) {
const [current, setCurrent] = useState({ path: entryPath, params: {} })
const [history, setHistory] = useState([current])
const loadFromHash = () => {
const pathFromHash = window.location.hash.split('#')[1]
setCurrent({ path: pathFromHash })
setHistory([{ path: pathFromHash }])
}
useEffect(() => {
window.addEventListener('hashchange', (e) => loadFromHash())
loadFromHash()
}, [])
const updateCurrent = ({ path, params }) => {
window.location.hash = `${path}`
setCurrent({ path, params })
}
const push = (path, params) => {
setHistory((prev) => [...prev, { path, params }])
updateCurrent({ path, params })
}
const back = () => {
history.pop()
const previousItem = history[history.length - 1]
setHistory(history)
updateCurrent(previousItem)
}
return (
<NavContext.Provider
value={{ setCurrent: updateCurrent, current, push, back }}
>
{children}
</NavContext.Provider>
)
}
Does your component need access to params?
No problem!
export function Cockpit() {
const { current } = useContext(NavContext)
const navParams = current.params
return <p>{JSON.stringify(navParams)}</p>
}
Do you want to navigate back and forth?
No problem! You can just use the push
and back
API from our NavContext
.
Conclusion
In most cases, you should go with react-navigation. It will save you a lot of time and just don't reinvent the wheel. However, within a side project that has just too few features to matter, you might learn a lot about routing from implementing it yourself.