Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/flipeador/react-router

Lightweight suspense-enabled routing library for React.
https://github.com/flipeador/react-router

javascript nodejs react-router reactjs router suspense-enabled

Last synced: about 11 hours ago
JSON representation

Lightweight suspense-enabled routing library for React.

Awesome Lists containing this project

README

        

# React Router

Lightweight [suspense-enabled][suspense] routing library for [React][react].

- Wrap routes in a `Router` component and optionally include a fallback page.
- Assign routes to pages with the `Route` component. Wrap the pages using [lazy][lazy].
- Set the path and document title in the `Route` component for each page.
- Use the `Link` component to navigate between pages or redirect to another website.
- Use any combination of `disabled`, `bold`, `style-1`, `style-2` and `style-3` classes to style links ([demo][codepen-link]).

> [!NOTE]
> If you are developing this library and you are importing it from another project, you will probably encounter errors because the library is importing a react module wich resolves to a different export object, resulting in two copies of the react package. The react import from your application code needs to resolve to the same module as the react import from inside the package. This error can be circumvented by using [`resolve.dedupe`][dedupe] (`resolve:{dedupe:['react']}`) to force to always resolve listed dependencies to the same copy from project root.

## Installation

```bash
npm i flipeador/react-router#semver:^1.0.0
```

## Examples

Example #1

```js
/* eslint-disable react-refresh/only-export-components */

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Router, Route, Link } from '@flipeador/react-router';

/**
* Simulates fetching the specified text from internet.
*/
function fetchText(text, delay=2000)
{
fetchText.cache ??= [];
if (fetchText.cache.includes(text)) return text;
// Throw a promise to trigger Suspense.
throw new Promise(resolve => {
setTimeout(() => { resolve(text); }, delay);
}).then(text => { fetchText.cache.push(text); return text; });
}

/**
* Home page function component.
* @example
* const Home = React.lazy(() => import('./pages/home.js'));
*/
function Home({ isPending })
{
const text = fetchText('Go to /profile');
console.log('Home:', isPending);
return (
<>

Welcome!


{text}


{ isPending &&

Loading profile...

}
>
);
}

/**
* Profile page function component.
* @example
* const Profile = React.lazy(() => import('./pages/profile.js'));
*/
function Profile({ isPending, routeParams })
{
const text = fetchText('Go to /home');
console.log('Profile:', isPending);
return (
<>

User ID: {routeParams.id}


{text}


{ isPending &&

Loading home...

}
>
);
}

const root = ReactDOM.createRoot(
document.getElementById('root')
);

root.render(
//
Loading...>}>
Unknown page>}>




//
);
```

Example #2

```js
/* eslint-disable react-refresh/only-export-components */

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Router, Route, useRouteProps } from '@flipeador/react-router';

function Home()
{
const { routeParams } = useRouteProps();
return (
<>

Welcome!


/:id {routeParams.id}


>
);
}

const root = ReactDOM.createRoot(
document.getElementById('root')
);

root.render(

Loading...>}>
Unknown page>}>
}/>



);
```

## License

This project is licensed under the **Apache License 2.0**. See the [license file](LICENSE) for details.

[react]: https://react.dev
[react-app]: https://create-react-app.dev
[lazy]: https://react.dev/reference/react/lazy
[suspense]: https://react.dev/reference/react/Suspense

[dedupe]: https://vitejs.dev/config/shared-options#resolve-dedupe

[codepen-link]: https://codepen.io/Flipeador/pen/ExeowOy