React Navigation from scratch

Most React apps use React-Router for navigation. React-Router has frequent breaking changes. But what matters most to us is learning about the theory and ideas of navigation. In this case we are not going to use React-Router , we are going to analyze in some project about some navigation stuff from scratch and understand some of the ideas and theory of navigation.

Project repository:

React Navigation from Scratch.

Here we can see the navigation menu and the associated routes.

Building a Reusable Route Component.

window.location is an object that is build into your browser. This object is going to be automatically updated anytime you navigate around to a different URL.

In this component, we can start to wire up an event listener . We’re going to listen for an event listener of pop state and anytime that occurs, we want to run a function that we’re going to call “onLocationChange”. Anytime this function is called, we have to tell the Route component to update itself or to really just render itself.

const onLocationChange = () => {
setCurrentPath(window.location.pathname);
};
window.addEventListener(‘popstate’, onLocationChange);

Implementing a Header for Navigation

Instead of using anchor elements we create a component called Link that will modify the behavior of the anchor elements.

In a normal web application, any kind of a traditional web app consisting of a a variety of different HTML documents, you might navigate some Web pages inside of your browser. Whenever you navigate to a page, your browser makes a request off to some sever and gets back in HTML document and its own set of javascript and CSS files.

Whenever a user clicks on a link, your browser makes an entire  another request to another server and gets back another HTML document and its own set of javascript and CSS files. This is how a traditional Web page handles navigation. We provide normal links whenever you click on a link you load up another HTML document.

This behaviour is not ideal inside of a react application. We have already, when we first come to our application, loaded up our index.js , HTML file, all the JavaScript, all the CSS. There is no reason in a React app for us to do a hard reload of the page and reload all these different assets. Instead will be really ideal is if we could click on these links, update the URL but not do a full page reload because a full page reload causes a whole bunch of network traffic that is not require just to change some very basic content on the screen.

Building a Link

Inside  the header component , we are going to make a new kind of component called a link. This component is just going to display a link on the screen that’s going to show a normal anchor element. But we are going to attach on click handler to that anchor element that is going to execute some very special logic whenever a user clicks on it.

Whenever a user clicks on one, those links, we are going to build a navigation event. This is going to be an object that is going to communicate to the rest of our application that the URL has just changed. This navigation event will then sent off to all of the different Route components inside of our app. When they receive this navigation event, they’re going to know that the world has just changed.

So in order to change the URL, but not do a full page refresh we are going to use a function that is built directly into the browser:

window.history.pushState({}, ”, href);
Each Route could detect the URL has changed, we produce and emit a navigation event:
const navEvent = new PopStateEvent(‘popstate’);
window.dispatchEvent(navEvent);

In another hand, whenever a user sees a link, he should be able to hold down command on your keyboard if you’re on Mac OS and click it or hold down control if you’re on Windows and click it. And in either case, that link should be opened up in a new tab. To preserve this behavior, before disabling the anchor element’s default behavior and applying our logic, we can check that these keys have been pressed and preserve their normal operation.

if (event.metaKey || event.ctrlKey) {
return;
}
event.preventDefault();
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published.