A tiny React router that works exactly as expected with native Javascript:
// App.js;; // Wrap it and you can use normal anchor links <div> <nav> <a href="/">Go Home</a> <a href="/about">About us</a> </nav> path === '/' && <div>Hello world!</div> path === '/about' && <div>About me</div> </div>;
You have to wrap your app with router()
and then both <a>
links and window.history.pushState()
will work as expected. It will trigger a re-render when any of these properties change: path
, query
or hash
.
If you have parameters or complex routes you can combine it with my other library pagex
for a cleaner syntax:
;; <div> </div>;
If a link has the attribute target
, then this library will ignore it and let the browser handle it. This is very useful for target="_blank"
, so that the link is opened in a new tab as usual. But it will also work with target="_self"
, where the router will ignore the link and thus perform a full-refresh.
An event named navigation
will be triggered on window
every time there's a re-render. You can see the parts with e.detail
, which is very useful for debugging:
// When loading /greetings?hello=world#nicewindow;
Internally, it works by using the bubbling events at the document level and then handling any link click. window.location
becomes the source of truth instead of keeping an context or global store, which makes it more reliable to interact with native Javascript or http events.
router(cb)
This HOC function accepts a callback, which will be passed an arguments with the props from above and these 3 extra props:
path
,pathname
(String): the current url path, similar to the nativepathname
. Example: for/greetings
it will be'/greetings'
. An empty URL would be'/'
.query
(Object | false): an object with key:values for the query in the url. Example: for/greeting?hello=world
it will be{ hello: 'world' }
.hash
(String | false): the hash value without the#
. Example: for/hello#there
it will be'there'
.
A fully qualified url will parse as this:
// /greetings?hello=world#nice;
Example: navigation bar
We can define our navigation in a different component. <a>
are native so they will work cross-components:
// Nav.js <nav> <a href="/">Home</a> <a href="/about">About</a> <a href="https://google.com/">Go to Google</a> <a href="/terms" target="_blank">Terms and Conditions</a> </nav>;
Then you can toggle the different pages in the main App.js:
// App.js;; <div> <Nav /> path === '/' && <div>Homepage</div> path === '/about' && <div>About us</div> </div>;
The Google link will open Google, and the Terms and Conditions link will open a new tab. Everything works as expected, in the same way native html works.
Example: scroll to top on any navigation
Add an event listener to the navigation event:
window;
<Link>
Example: simulating the Just an example of how easy it is to work with react-plain-router
, let's see how to simulate the component that the library react-router-dom
defines with this library
// components/Link.js <a href=to ...props />;
Then to use our newly defined component, we can import it and use it:
// Home.js;; <Link to="/about">About us</Link>;
But you can just use native links:
// Home.js; <a href="/about">About us</a>;
Example: manual navigation
To trigger manual navigation you can use the native history.pushState()
as explained in the amazing Mozilla Developer Network:
// src/actions/login async { const payload = await ; ; windowhistory;};