It will be simple and to the point
Recently while working with Jobsbuddha mobile app I needed a router to navigate between different screens of the app. Instead of installing and using a routing library I decided to create my own simple implementation of a router.
The reasons for that decision was
- Installing and using a whole routing library just for navigation back and forth between two screens seems a waste of time also it will introduce unwanted dependencies.
- It’s simple and very much fun to implement your own router. 😃
Let’s define how we are going to use our router
I think it is very important to decide how we will be using components that we are about to create. It gives us a clear picture of how your component should be built, what props to pass etc.
Our router implementation will have two components
Router will be the topmost component which will contain all the history of the navigation alongside the currently
activeRoute, this component will also be responsible for providing methods to update the currently
activeRoute to its children Route components.
This component is just a wrapper around the components we want to render as routes. It will be responsible for registering these components as Routes so we can use the Route
name to navigate between them.
Let’s dive in
Let’s have a look at the code
We will have a topmost component
Router and inside it, we will have different routes with a unique name and a component passed to every route. The passed component will be rendered when its route becomes active. The
name will be used as an
key while navigating between the routes.
Let’s create our Route component
From the props, we are extracting
component and all of the other props are stored inside
routeProps. We then store the component in
ComponentToRender because in react all of the React components names should start with a capital letter, at last, we pass all of the
routeProps to the component.
In case you are wondering from where these
routeProps will be passed, these props will be passed from the topmost
Let’s create our Router component
We started by defining two state variables
history. As the name suggests the
activeRoute will contain the name of the currently active route and
history will store the history of our navigation so we can move backward or forward.
As you can notice we are using
useState hook so we also get two updater functions
updateHistory to update our state variables.
By default, the
activeRoute will be
null and the history will be an empty array.
Let’s create a function which will allow us to navigate between the routes
In the function
go we take a
route as an argument. This
route should be a valid route name which was provided to any
Route component. We use
setActiveRoute and update the currently active route to the
Next, we check if the new
route is the same as the currently active route if that is the case we didn’t update the
history and exit the function. For e.g.
if we are already on the home route and we attempt to navigate to home route a new entry shouldn’t be added to our history array.
if the provided
route is not the same as the current route we add the route to our
history and update the
history in the state with
Now let’s actually render our active route.
Firstly we extract the
children from the
Router props. In the 20th line, we are concatenating the
children to an empty array.
The reason for doing this is if there is only one
Route passed to
Router then the
children will be an
object and if multiple
Route components are passed to
Router then the
children will be an
So by concatenating the
children to an empty
array we ensure that the
childrenArray will always be
array so we don’t have to worry about working with different data types.
In line 22 we are finding which child to render by matching the
activeRoute. We can access child props with the property
If there is no route which matches with our current active route we return
If we found a child which matches our current active route then we clone that child and add additional props to it, remember
routeProps? Yeah, here we are passing these props to our
We pass a
routerobject which contains the
go method. Now we can use
router.go to navigate between routes.
At last, we have to provide some kind of mechanism so the first route will always be the initial route.
At line 22 we define a
useEffect which runs every time the
activeRoute gets changed. Inside the
useEffect we check if
activeRoute doesn’t exist ( null, undefined ) and we have at least one route. If the condition is
true we will take the name of the first route from the
childrenArray and set it as
activeRoute so if anytime
null the first route will automatically be selected as the initial route.
Now let’s use the router.go method inside our components.
In our props the
router object will be present. We simply called
route.go('home') to navigate from
So that’s how I created my own router in react. In case you are wondering we just saved
history and didn’t do much with it. I will encourage you to try that out create your own
goBack function. In my case, I didn’t need it yet but I implemented history anyway because I already knew we will be needing the
history in the long run.
keep sharing 😃
I am available to give a public talk or for a meetup hit me up at firstname.lastname@example.org if you want to meet me.
Really loved this article ?
Please subscribe to my blog. You will receive articles like this one directly in your Inbox frequently.