RoyalZSoftware
Back to Blog

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

Alexander Panov 2023-06-01 2 min read
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.

More articles

Building a Web Server in Go: A Beginner's Guide

Building a Web Server in Go: A Beginner's Guide

Oleksandr Vlasov 2024-11-26 3 min read
React Hooks — createContext, useContext, useMemo

React Hooks — createContext, useContext, useMemo

Oleksandr Vlasov 2024-10-23 4 min read
Mastering Git Rebase Interactive: Squashing Commits for a Clean History

Mastering Git Rebase Interactive: Squashing Commits for a Clean History

Alexander Panov 2024-10-21 2 min read