houter v1.0.10
houter
A tiny routing solution inspired by wouter and React Route for React App .
- Familiar React Route API & patterns:
<BrowserRouter>
,<HashRouter>
,<Route>
,<Link/>
,<Redirect/>
and<Switch/>
. - Has hook-based API for more granular control over routing (like animations): useLocation, useRoute and useRouter.
- Written in TypeScript and will make it easier for you to type your React code.
Install
npm install houter
Get started
Check out this demo app below in order to get started:
import { BrowserRouter, Route } from 'houter';
const App = () => (
<BrowserRouter>
<Route path="/" render={() => <div>Home</div>} />
<Route
path="/users/:name"
render={({ match }) => <div>{match.params.name}</div>}
/>
<Route path="/inbox" component={InboxPage} />
</BrowserRouter>
);
Core API
Houter has two kinds of APIs:low-level React Hook-based API and more traditional component-based API similar to React Route's one.
The list of method available
Component API:
Hooks API:
Component API
<BrowserRouter/>
A <Router>
that uses the HTML5 history API (pushState, replaceState and the popstate event) to keep your UI in sync with the URL.
import { BrowserRouter } from 'houter';
<BrowserRouter
basename={optionalString}
forceRefresh={optionalBool}
getUserConfirmation={optionalFunc}
keyLength={optionalNumber}
>
<App />
</BrowserRouter>;
props:
basename: string
If all the URLs in your app are relative to some other "base" URL, use the basename option. This option transparently adds the given string to the front of all URLs you use.
import { BrowserRouter } from 'houter';
<BrowserRouter basename="/abc" />;
history.listen(location => {
console.log(location.pathname); // /home
});
history.push('/home'); // URL is now /abc/home
forceRefresh: boolean
If true the router will use full page refreshes on page navigation. You probably only want this in browsers that don’t support the HTML5 history API.
getUserConfirmation:function
A function to use to confirm navigation with the user.
import { BrowserRouter } from 'houter';
<BrowserRouter
getUserConfirmation={(message, cb) => cb(window.confirm(message))}
/>;
keyLength: number
The length of location.key
More information at createBrowserHistory.
<HashRouter/>
A <Router>
that uses the hash portion(window.location.hash) to keep your UI in sync with the URL.
import { HashRouter } from 'houter';
<HashRouter
basename={optionalString}
hashType={optionalString}
getUserConfirmation={optionalFunc}
/>;
basename:string
The base URL for all locations. A properly formatted basename should have a leading slash, but no trailing slash.
hashType:string
By default <HashRouter/>
uses a leading slash in hash-based URLs. You can use the hashType option to use a different hash formatting.
<HashRouter
hashType="slash" // the default
/>;
history.push('/home'); // window.location.hash is #/home
<HashRouter
hashType="noslash" //Omit the leading slash
/>;
history.push('/home'); // window.location.hash is #home
<HashRouter
hashType="hashbang" //Google's legacy AJAX URL format
/>;
history.push('/home'); // window.location.hash is #!/home
More infomation at createHashHitory.
<Router/>
The common low-level interface for all router components.The most common use-case for using the low-level <Router>
is to synchronize a custom history with a state management lib like Redux or Mobx,or using the history instance outside the React App.
import {creteBrowserHistory,createHashHistory} from 'history'
const hashHistory = createHashHistory();
const browserHistory = createBrowserHistory();
//Using in modern web browsers that support the HTML5 history API.
<Router
history={browserHistory}
>
<App/>
</Router>
//Using in legacy web browsers.
<Router
history={hashHistory}
>
<App/>
</Router>
More information at history
<Route/>
<Route/>
is a component rendered some UI when a location matches it's path.
Route render methods:
Houter provides multipile ways to render something with <Route/>
:
import { BrowserRouter } from 'houter';
const App = () => {
return (
<BrowserRouter>
<Route
path="/"
exact
render={({ location, match, history }) => <div>Home</div>}
/>
<Route path="/foo" component={Foo} />
<Route
path="/boo"
children={({ location, match, history }) => <div>boo</div>}
/>
</BrowserRouter>
);
};
Route props:
All three render methods will be passed the same three route props:
Props:
path:string|string[]
Any valid URL path or arrays of paths that path-to-regexp@^3.0.0 understands.
Route always match without a path.
component:ReactComponent
A React component to be rendered when current location matches the route's path.It will be rendered with route props.
render:function
Inline rendering and wrapping without the undesired remounting explained above.
Warining:if you using component and render both in the same <Route/>
,the component prop will takes precedence over render.
children:function|ReactElement
<Route/>
always rendering the children whether the current location matches route's path or not.
exact:boolean
When true the regexp will match to the end of the string.(default: false)
path | location.pathname | exact | maches |
---|---|---|---|
/boo | /boo/foo | true | false |
/boo | /boo/foo | false | true |
strict:boolean
When true the regexp allows an optional trailing delimiter to match. (default: false)
path | location.pathname | strict | maches |
---|---|---|---|
/boo/ | /boo | true | false |
/boo/ | /boo | false | true |
sensitive:boolean
When true the regexp will be case sensitive. (default: false)
path | location.pathname | sensitive | maches |
---|---|---|---|
/BOO/ | /boo | true | false |
/boo/ | /boo | true | true |
/Boo/ | /boo | false | true |
location:object
<Switch/>
<Switch/>
always render the first matched <Route/>
component.
See the differences between these two demo below:
import { Switch, Route } from 'houter';
const App = () => {
return (
<Switch>
<Route path="/" component={Home} />
<Route path="/foo" component={Foo} />
<Route path="/boo" component={Boo} />
</Switch>
);
};
location.pathname = '/';
//Render <Home/>
location.pathname = '/foo';
//Render <Home/>
location.pathname = '/boo';
//Render <Home/>
import { Switch, Route } from 'houter';
const App = () => {
return (
<Switch>
<Route path="/foo" component={Foo} />
<Route path="/boo" component={Boo} />
<Route path="/" component={Home} />
</Switch>
);
};
location.pathname = '/';
//Render <Home/>
location.pathname = '/foo';
//Render <Foo/>
location.pathname = '/boo';
//Render <Boo/>
<Link/>
<Link/>
component renders an <a />
element that, when clicked, performs a navigation. You can customize the link appearance by providing your own component or link element as children:
import { Link } from "houter";
// It will produce the ReactElement like
//`<a href="/" onClick={()=>history.push('/)}>Hello!</a>`
<Link to="/">
<a>Hello!</a>
</Link>
// It will produce the ReactElement like
//`<a href="/" onClick={()=>history.push('/)}></a>`
<Link to="/">
</Link>
// It will produce the ReactElement like
//<a href="/" onClick={()=>history.push('/)}>
// <div>Hello!</div>
// <span>Welcome!</span>
//</a>`
<Link to="/">
<div>Hello!</div>
<span>Welcome!</span>
</Link>
// It will produce the ReactElement like
//<App href="/" onClick={()=>history.push('/)}>Hello!</div>
<Link to="/">
<App>Hello!</App>
</Link>
<Redirect/>
<Redirect/>
will performing a redirect to a path provided when mounted.
Witout a provided path, <Redirect/>
will doing nothing when mounted.
import { Redirect } from 'houter';
//It will redirect to '/foo' when mounted.
<Redirect path="/foo" />;
location
A Location represents where the app now,where the app want to go,or where the app it was.
It looks like this:
{
key:"ac3df4",
pathname:'/',
search:'?a=b&c=d',
hash:"#",
state:{
[key]:value
}
}
The route will provide location object in a few places:
<Route render/>
as ({ location }) =>()<Route component/>
as this.props.location<Route children/>
as ({location}) =>()useRoute()
as { location } = useRoute()useRouter()
as { location } = useRouter()
match
A Match object represents how a <Route/>
matched the current URL.
It contains these properties below:
type match = {
isExact: boolean;
params: {
[key]: value;
};
path: string;
url: string;
};
The list of ways obtaining match
object:
<Route render/>
as ({match}) =>()<Route component/>
as this.props.match<Route children/>
as ({match}) =>()useRoute()
as {match} = useRoute()useRouter()
as { match } = useRouter()
history
A History object offers a set of methods to perform navigation,it refers to the history package.
See more infomations at history.
Hooks API
React's new "Hooks" APIs give function components the ability to use local component state, execute side effects, and more.
useRouter
:
The useRouter
hooks let you have access to the lastest history object and the closest \<Route/>'s match object.
const { location, match, history } = useRouter();
useRoute
:
The useRoute
hook make accessing router directly easier . You can check if particular route
matches th current location by using an useRoute
hook .
useRoute(
options:string|string[]|{
path?:string|string[],
exact?:boolean,
sensitive?:boolean,
strict?:boolean
}={}, location?:object);
import { useRoute, BrowserRouter } from 'houter';
const CustomizeRoute = () => {
//You can pass any valid URL path or array of paths.
const { match, location, history } = useRoute('/foo/:boo');
const { match, location, history } = useRoute(['/foo/:boo']);
// or passing an object with specific config.
const { match, location, history } = useRoute({
path: '/foo/:boo', // or ["/foo/:boo",'/',...And any valid URL path you want to be matched]
strict: false,
sensitive: false,
exact: false
});
return (
<div onClick={() => history.push('/')}>
Location:{location.pathname}
params:{match.params.boo}
</div>
);
};
useLocation
You can get access to the location object’s properties and performing a navigation via the useLocation hook.
const App = () => {
const [location, push, replace] = useLocation();
return <div onClick={() => push('/')}>go to Home</div>;
};
License
houter is MIT licensed