@lxjx/react-router-manager
v1.7.0
Published
* support for routing level keepAlive, keep the route component states. * routing animation without performance loss * 404 custom、onRouteChange、route meta data、query parse、auth page、etc. * centrally manage route * conventional route
Downloads
3
Readme
✨feature
- support for routing level keepAlive, keep the route component states.
- routing animation without performance loss
- 404 custom、onRouteChange、route meta data、query parse、auth page、etc.
- centrally manage route
- conventional route
🎨example
📦install
npm install @lxjx/react-router-manager
# or
yarn add @lxjx/react-router-manager
🤔usage
basic
The most basic usage is almost the same as react router
import React from 'react';
import { HashRouter, Link } from "react-router-dom";
import {
RouterManager, Route
} from '@lxjx/react-router-manager';
// pages
import Home from './home';
import About from './about';
function App() {
return (
<HashRouter>
<RouterManager>
<div>
<Link to="/">home</Link>
<Link to="/about">about</Link>
</div>
<Route
path="/"
component={Home}
exact // receive all Route props except for render、children
/>
<Route
path="/about"
component={About}
/>
</RouterManager>
</HashRouter>
);
}
export default App;
keepAlive
Pass in keepAlive so that a page will not be destroyed when it is unmounted
<XX>
<Route path="/page1" keepAlive component={Page1} />
<Route path="/page2" component={Page2} />
</XX>
use triggerPageUpdate to reload cached pages
triggerPageUpdate('/page1')
auth page
<RouterManager
preInterceptor={({ location }) => {
if (!token && location.pathname !== '/login') return (
<div>Please log in first! <a href="/login">to login</a></div>
)
}}
</RouterManager>
You can also use within
prop
function withLogin(Component) {
return function LoginHOC(props) {
if (!token && props.location.pathname !== '/login') return (
<div>Please log in first! <a href="/login">to login</a></div>
)
return <Component {...props} />
}
}
<Route component={Page2} path="/page2" within={[withLogin]} />
custom 404 page
function N404() {
return <div>404</div>;
}
<RouterManager notFound={N404} >{...}</RouterManager>
page meta
<Route component={Page2} path="/page2" meta={{ title: 'page 2' }} />
// page component
function Page2({ meta }) {
return (
<div>
<Helmet>
<meta charSet="utf-8" />
<title>{meta.title}</title>
<link rel="canonical" href="http://mysite.com/example" />
</Helmet>
</div>
)
}
events
<RouterManager
onNotFound={({ location }) => {
console.log('404', location.pathname);
}}
onRouteChange={({ location }) => {
console.log('change', location.pathname);
}}
>
</RouterManager>
conventional route
Use convention routing, via webpack require.context API
- open config
<RouterManager conventionRouter></RouterManager>
- conventional dir
/proj
/src
/Index.jsx // capitalize is require
/News.jsx
/About.jsx
// generated like =>
<Route path="/Index" exact component={/* Index.jsx module */}>
<Route path="/News" exact component={/* News.jsx module */}>
<Route path="/About" exact component={/* About.jsx module */}>
- complex construction
/proj
/src
/Index
/Index.jsx // => / exact
/News
/News.jsx // => /News exact
/Detail.jsx // => /News/Detail
/Center
/Center.jsx // => /Center exact
/Info.jsx // => /Center/Info
- config by static prop
import React from 'react';
const Index = () => {
return (
<div>
<div>Home Page</div>
</div>
);
};
Index.routerConfig = {
keepAlive: true,
meta: { title: 'home page' },
// any Route Props
}
export default AddProduct;
typescript tips
Use RouteComponent to declare component
import React from 'react';
import { RouteComponent } from '@lxjx/react-router-manager';
type Props = {/* ... */};
type Query = {/* ... */};
type Param = {/* ... */};
type Meta = {/* ... */};
const Index: RouteComponent<Props, Query, Param, Meta> = ({
match, // type ✅
}) => {
return (
<div>
<div>Home Page</div>
</div>
);
};
// type ✅
Index.routerConfig = {
keepAlive: true,
meta: { title: 'home page' },
}
export default AddProduct;
static props
you can configure the route component with static properties
const Index: RouteComponent<Props, Query, Param, Meta> = () => {
return (
<div>
<div>Home Page</div>
</div>
);
};
Index.routerConfig = {
// pass any Route props
keepAlive: true,
meta: { title: 'home page' },
}
🎈API
RouterManager
manage Route components
export const RouterManager: React.FC<{
/** custom 404 page components */
notFound?: React.ComponentType<RouteComponentProps>;
/** trigger on pathname not found */
onNotFound?: ({ location: Location, history: History }) => void;
/** trigger on pathname change */
onRouteChange?: ({ location: Location, history: History }) => void;
/** If reactElement or null is returned, prevent the routing node from rendering and render the returned node */
preInterceptor?: (props: RMMatchProps) => React.ReactElement | null | void;
/** Global Route props, covered by local props */
routeBaseProps?: RMRouteProps;
/** Use convention routing, via webpack require.context API */
conventionRouter?: boolean;
/** trigger on convention routing config created */
onConventionRouterConfigCreated?: (conf: RMRouteProps[]) => void;
}>;
Route
Route components, used to configure a routing item, which is a superset of the Route component of react-router
export interface RMRouteProps extends RouteProps {
/** animate transition type */
transition?: 'bottom' | 'right' | 'fade';
/** no destroy when page leave */
keepAlive?: boolean;
/** extra meta passed to the page component */
meta?: { [key: string]: any };
/** enhanced component, used for authentication, layout, etc. this hoc component should pass all received props like `<Component ...{props} />` */
within?: RMWithinHOC[];
/** page className */
className?: string;
/** page style, avoid using such as display、opacity、transform、z-index, etc. */
style?: React.CSSProperties;
/** route component */
component?:
| RouteComponent
| React.ComponentType<RouteComponentProps>
| React.ComponentType<any>;
}
RouteComponent
Used for routing component declaration
export interface RouteComponentProps<Query = any, Params = any, Meta = any> {
match: match<Params> & { query: Partial<Query> };
location: Location;
history: History;
meta: Meta;
pageElRef: React.RefObject<HTMLDivElement>;
}
// with static config
export interface RouteComponent<
Props = any,
Query = any,
Params = any,
Meta = any
> extends React.FC<RouteComponentProps<Query, Params, Meta> & Props> {
routerConfig: RMRouteProps;
}
triggerPageUpdate
invalid and overload the page cache of keepAlive
export const triggerPageUpdate: (path: string) => void;
🌹other
page base style
built-in basic styles for routing components that allow you to handle routing conveniently
.m78-router-wrap {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: hidden;
}
.m78-router-page {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
background-color: #f6f6f6;
-webkit-overflow-scrolling: touch;
}
it can:
- prevent document flow confusion
- no need to care about html, body, #root height, width...
- scroll bars are maintained by the page itself, rather than using public document scroll bar, which can effectively prevent scrolling confusion
- no need to lock the scroll bar of the document when modal/dialog is show
- It is more convenient to manage pages
query
when the query is detected, the internal will be decoded by the query-string and mounted on the match object.
// http://xx.xx.cn/user?name=lxj&age=25
// component inside
props.match.query // => { name: 'lxj', age: 25 }