Skip to main content

Command Palette

Search for a command to run...

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

Published
2 min read
How I built a simple react-navigation clone in 5 minutes
A

Software developer and CEO at RoyalZSoftware. I build web applications for startups with Ruby on Rails, Angular and React.

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 from this blog

R

RoyalZSoftware

76 posts

This blog is about software development best practices and insights from RoyalZSoftware. Read it to advance your coding journey or to understand what we are doing for your software project.