7.6 KiB
Why Config Router? 🤔
Config Router 👋 is an attachment lib to React Router v5.x. It works well with React Router, helping with route configuration, route rendering and route guarding.
If you are a Vue Router user before, it is quite easy for you to get started. Of course this project is not as mature as Vue Router. 😂
Features 🎉
- ✔️ Config route by declaring the routes array like that in Vue Router.
- ✔️ Render routes by importing and using a single component called
RouterView
👀. - ✔️ Guard routes that should be accessed only by authorized users.
- ⭕ More is on the way...
Usage 📖
You can use this package in either react-jsx
projects or react-tsx
projects. Take project with vite
, react
and typescript
for example.
Add React Router
Dependencies
yarn add -s react-router-dom
yarn add -D @types/react-router-dom
Or with
npm
.npm i -s react-router-dom npm i -D @types/react-router-dom
Add Config Router
Dependencies
After adding React Router dependencies, you can add config-router
to your project.
yarn add -s @syy11cn/config-router
Or with
npm
.npm i -s @syy11cn/config-router
Create a Configuration File
Create a configuration file in src/routes
(for example config.ts
).
Here is a sample configuration.
// First you should import `routeType`.
import { routeType } from '@syy11cn/config-router';
// Import components to be used.
import Index from '../views/Index';
import Portal from '../views/Portal';
import Test from '../views/Test';
import Error from '../views/Error';
// Routes config.
const routes: Array<routeType> = [
{
path: '/home',
component: Index,
routes: [
{
path: '/home/test',
component: Portal,
},
{
path: '/home',
component: Test,
},
],
},
{
path: '/404',
component: Error,
},
{
path: '/',
component: Portal,
},
];
export default routes;
As shown above, routes config is an array consists of routeType
items.
routeType
is declared as follows,
import * as React from 'react';
interface routeType {
path: string;
component: React.ComponentType<any>;
exact?: boolean;
routes?: Array<routeType> | undefined;
}
export default routeType;
which means the routes
field of an item is another routeType
array.
Prompt in Writing Configuration
- The root route should always be the last item in a
routeType
array. - Never set
exact: true
when there is aroutes
field in therouteType
item. - Fields
path
andcomponent
are required. Fieldsexact
androutes
are optional.
Use RouterView
Component
In main.tsx
, add <Router>
outside the <App>
Component.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter as Router } from 'react-router-dom';
ReactDOM.render(
<React.StrictMode>
<Router>
<App></App>
</Router>
</React.StrictMode>,
document.getElementById('root')
);
Then in App.tsx
, use RouterView
component.
import { FunctionComponent } from 'react';
import { Layout } from 'antd';
import { RouterView } from '@syy11cn/config-router';
import routes from './routes/config';
import './App.css';
const { Header, Content, Footer } = Layout;
interface AppProps {}
const App: FunctionComponent<AppProps> = () => {
return (
<div align=center className="App">
<Header></Header>
<Content>
<RouterView
routes={routes}
onEnter={function (to, next): void {
console.log('onEnter');
next();
}}
></RouterView>
</Content>
<Footer></Footer>
</div>
);
};
export default App;
The RouterView
component here would render routes in the <Content>
component. Rendered components would take the place of RouterView
.
Nested Routes
In the sample configuration, there is a nested route in component Index
. Notice that no matter where you use a RouterView
, there should be a routes
attribute added on it.
Therefore, in src/views/Index.tsx
, the component should receive a routes
property, which includes nested routes under Index
component.
import { FunctionComponent } from 'react';
import { RouterView } from '../routes';
import { routeType } from '@syy11cn/config-router';
interface IndexProps {
routes: Array<routeType>;
props: any;
}
const Index: FunctionComponent<IndexProps> = ({ routes, props }) => {
console.log('Index View');
return (
<div align=center>
<h1>This is Index</h1>
<RouterView
routes={routes}
onEnter={(to, next) => {
if (to === '/home/test') {
next();
} else {
next('/404');
}
}}
></RouterView>
</div>
);
};
export default Index;
Route Guarding
Write a Function
in onEnter
hook, and the Function
would be called before rendering the routes.
Your Function
should receive two properties, which are named to
and next
.
to
is astring
referring which route a user want to meet.next
is aFunction
. If you pass a string to it,next
would help you redirect to that path. While if you callnext
without passing a property, the component would just let user go where they want.
The same sample code as above.
import { FunctionComponent } from 'react';
import { RouterView } from '../routes';
import { routeType } from '@syy11cn/config-router';
interface IndexProps {
routes: Array<routeType>;
props: any;
}
const Index: FunctionComponent<IndexProps> = ({ routes, props }) => {
console.log('Index View');
return (
<div align=center>
<h1>This is Index</h1>
<RouterView
routes={routes}
onEnter={(to, next) => {
if (to === '/home/test') {
next();
} else {
next('/404');
}
}}
></RouterView>
</div>
);
};
export default Index;
In this situation, when a user want to access /home/test
, corresponding route and component would be rendered. When accessing /home
or other routes begin with /home
, the user would be redirect to a 404
page.
Contribution 💻
Contributions are welcome. Just fork this repo and send PRs.
Any questions while using this package, please open an issue and I would manage to solve it as soon as I receive the message.
About 🙌
License
Copyright (c) 2021, Yiyang Sun