@realmjs/react-navi
v4.7.2
Published
Navigator for react client
Downloads
7
Readme
react-nav
Providing useful Navigator component, nav and page handler
Installation
npm install --save @realmjs/react-navi
Running example demo
npm start
Checkout the example at localhost:3000
Walkthrough Tutorial
TBD
Quick Simple Usage
"use strict"
import React, { Component } from 'react'
import { Navigator } from 'react-navi'
function Home({ nav }) {
return (
<div>
<h2> Home </h2>
<p>
<button onClick = { e => nav.navigate('about') }> About </button>
</p>
</div>>
);
}
function About() {
return (
<div>
<h2> About me </h2>
<p>
<button onClick = { e => nav.navigate('home') }> Home </button>
</p>
</div>>
);
}
function Error({ route }) {
const {code, text} = route.data;
return (
<div>
<h2> Error: {code || 'Unknown'} </h2>
<p> {text || 'Unexpected unknown error has occured'} </p>
</div>
);
}
const routes = {
home: {
Page: Home,
url: '/'
},
about: {
Page: About,
url: '/about'
},
error404: {
Page: Error,
url: '/error/404',
data: {
code: 404,
text: 'Page not found'
}
}
};
function Demo(props) {
return (
<div>
<Navigator routes = {routes}
initialRoute = 'home'
fallbackRoute = 'error404'
{...this.props}
/>
</div>
);
}
Either click to the buttons or make change in your browser address bar to navigate to page. For the url paths that does not match with those in routes
will be redirected to fallbackRoute
, i.e. /error/404
in this example.
Any Props passing to Navigator
will be passed to Page
element.
It is a simple usage. However, Navigator
can do much more than that.
Concept
@realmjs/react-navi
is built around the route
object and navigator
component.
Route
object
A route
object defines a route
controlled by Navigator
.
route {
url: String, // path of url for this route, does NOT include hostname
Page: React.Component, // A React component used to render your Page
data: Object || Promise, // data you can access from your Page via props.route.data
title: String, // Title the browser will display when entered into this route
resolve: Function // Function will be called if the promise function of data is resolved
reject: Function // Function will be called if the promise function of data is rejected
redirect: String // Name of the route that this route will be redirected to
}
url
: is the path of route
and case insensitive. If your app does not need url, you can ommit it and set prop noUrl = {true}
in Navigator
- Route parameter is supported. For example:
/document/:docid
. You can access these parameters inroute.params
.
data
: is the data you want to pass into the rendered Page element of this route
. It can be an object or a function returning a promise.
A promise is useful if you want the
navigator
to prepare data before actually navigating to Page. The data function receives two arguments:params
which isroute.params
andprops
which is the react props passing to the element. Page is loaded only if the function is resolved.const route = { ... data: ({params, props} => fetch(`${props.endpoint}/${params.id}`)), ... };
Resolved data is accessed from the Page via
props.route.data
resolve
: the callback function which is called if the data promise function is resolved, accept the resolved data as the function argument.
reject
: the callback function which is called if the data promise function is rejected, accept the rejected error as the function argument.
Page
: is the React component you design for route
. The Navigator
will pass the following helper props to your Page
element:
route
: this route object represents the current route. It contains the actual url path, the resolved data, the params object extracted from the url path and an isActive flag indicating whether this route is active or not.const route = { url: '/page/about/:id', Page: Page, data: ({params, props}) => fetch(`/person/${params.id}`) }; function Page({ route }) { const { url, data, params, isActive } = route; console.log(url); // example output: /page/about/jon console.log(params); // example output: { id: 'jon' } console.log(data); // example output: { person: 'Jon Snow', email: '[email protected] } console.log(isActive); // example output: true or false return ( <div> <h2> Person: {data.person} </h2> <p> {data.email} </p> </div> ); }
page
: the page helper providing some helper utilities for page. You can setup page event observer (load, enter, leave...), create page popup or get data passed to page via navigator routine.
redirect
: the name of route that this route should be redirected to. For example:
const routes = {
home: {
url: '/',
Page: Home
},
landing: {
url: '/landing',
redirect: 'home'
}
};
title
: The document title the browser will display for thatroute
. Using {:param} and {{data}} for dynamic title. For example:{ url: '/welcome/:team', data: () => fetch('api/name'), title: "Welcome {{name}} from {:team} team", }
When accessing /welcome/dev with resolving data { name: 'awesome' }, the title will be "Welcome awesome from dev team"
Navigator
Component
Navigator
component controls all routes registered to it. Each time user navigate to a route (by calling API or change url in address bar), it will render and display Page
component of that route
.
For each rendered Page
, Navigator
will inject route
object and page
object into props
.
Note that there is only one Navigator
for entire application.
Navigator
Component Properties:
routes
(Object): Routes object to be registered into Navigator
initialRoute
(String): Name of the route
that will be active at initial if noUrl
is true
fallbackRoute
(String): Name of the route
that Navigator
will redirect to if the url
does not match any route
in registered routes
. It is ignored if noUrl
is false
. Note that navigate to an unregistered route by navigate API
will not redirect to fallbackRoute
, but reject
with an error.
onChangeRoute
(Function): Function that is called when active route is changed. It receives the route
object of active route as the arguments.
onEnterPage
(Function): Function that is called when navigate is enter a Page but before the page is rendered. It receives the route
object of active route as the arguments.
onPageRendered
(Function): Function that is called after Page is rendered, It receives the route
object of active route as the arguments.
noUrl
(Boolean): Default is false
, define whether your application should use url
or not. If set to true
, route
object will require url
, navigate to a route
will update url
in address bar and you can also navigate by typing url
from there.
routeHandler
(Function): The function will be called when creating navigator
, with routeHandler
in the argument. routeHanler
can be used to call navigate
API. [Deprecated]
// example of using routeHandler
...
render() {
return (
<Navigator routes = {routes}
onChangeRoute = { route => console.log('Active route is' + route.url) }
onPageRendered = { route => console.log('Rendered page for route ' + route.url) }
onEnterPage = { route => console.log('Enter page for route ' + route.url) }
{...this.props}
/>
)
}
Route Stack
The Navigator
will create route stack in session storage automatically. Each time user navigate to a route
, it will add to the route stack.
Global nav
Object
@realmjs/react-navi
expose the global nav
object. It can be used to navigate route, create global popup
or create toast
from anywhere in your application
navigate (name, options)
name
(String): name of route navigate to
options
(Object): optional
data
(Object): Data passing toPage
and can be accessed viaprops.page.data
.noUpdateUrl
(Boolean): defalt isfalse
, set totrue
will not update url [Deprecated]reload
(Boolean): default isfalse
, set totrue
will cause aweb page reload
when navigating.
This function return a promise
popup(PopupComponent, options, callback)
PopupComponent
(React Component): A React Component design the popupoptions
(Object): optionaldata
(Object): Data passed toPopup
viaself
objectoverlay
(Boolean): Default isfalse
, set totrue
will createpopup
in an overlay layeronClickOverlay
(Function): The function is called whenever user click to overlay. Acceptself
as the function argument.
callback
-Function
: optional, a callback provideself
object toresolve
orreject
popup.
This function return a promise
that resolve
or reject
by the popup
via self
object
Popup self
object
The Popup
component receive self
object via its props
.
self {
data: Object,
onClickOverlay: Function,
resolve: Function,
reject: Function
}
Note that the popup created by nav
is global.
Create toast
Toast
can only be created by nav
object. The API is veri similar to popup APi
except that it does not return anything
toast(ToastComponent, options, callback)
PopupComponent
-React Component
: A React Component design the popupoptions
-Object
: optionaldata
-Object
:data
passed toToast
viaself
objectbottom
-Boolean
: defaultfalse
, if set totrue
toast will float up from bottom
callback
-Function
: optional, a callback provideself
object toclose
toast.
Toast self
object
The Toast
component receive self
object via its props
.
self {
data: Object,
close: Function
}
Example using nav
object
import { nav } from 'react-navi'
import Popup_Loading from './popup/Popup_Loading'
import Toast_System from './toast/Toast_System'
nav.navigate('welcome', { data: {
user: 'Awesome Dev'
}});
nav.popup(Popup_Loading, self => {
setTimeout(() => {
self.resolve('Loading Timeout 3 seconds');
}, 3000);
});
nav.toast(Toast_System, { data: 'System message' }, self => {
setTimeout(() => {
self.close();
}, 2000);
});
Injected page
object
For each rendered Page
, Navigator
will inject a page
object into Page props
. This page
object allow Page
to setup event listeners and create page's Popups
.
Page events
Following page event are supporting:
load
This event is fired when a route
is active for the first time. When a route
is active, it will be pushed into a routeStack
manage internally by Navigator
. When it is inactive, Navigator
will hide
its page
. When it is active again, Navigator
simply unhide
its page
and load
event is not fired.
beforeEnter
This event is fired every time a route
is going to active by a navigate
API call.
enter
This event is fired every time a route
is active and its page
is shown up.
leave
This event is fired every time a route
is going to inactive
by a navigate
API call.
These event
can be registered via page
object. Example below:
class Page_Home extends Component {
constructor(props) {
super(props);
props.page.onLoad(e => console.log('# Load Page'));
props.page.onBeforeEnter(e => console.log('# Before Enter Page'));
props.page.onEnter(e => console.log('# Enter Page'));
props.page.onLeave(e => console.log('# Leave Page'));
}
render() {
// render code...
}
}
Create Popup
It is very useful to create a popup
using page
object, simple by calling popup
API. The API is identical with nav.popup
.
Note that popup
created from a page
will only exist in that page
. popup
created by nav
object will exist in global.
TODO:
- Animation for popup & page
- Add Unit tests
- Validate href not duplicated
- Fix error: enter invalid route without fallbackRoute defined.
- HOw redirect route use to redirect to route with param?