An experiment on using State-based routing with React components.
can-route-react
is a collection of React components that help with routing. The components are modeled after the ones found in React Router. Here's the current list of components:
- The Route Component - Show or hide components based route data.
- The Link Component - Create links from route state. (coming soon)
State-based routing decouples the URL from your application's routing. Routing rules and URLs are created from a state object. It's easier to change URL schemes when needed. The can-route module is arguably the best state-based router available, so it was selected for its core routing functionality.
Before you can use the components, you'll need to setup can-route. Here's a basic example:
import route from 'can-route';
import DefineMap from 'can-define/map/map';
// Create a DefineMap to setup route attributes.
const RouteMap = DefineMap.extend({
'*': {
serialize: true
},
// Define `page` as a string type.
page: 'string'
});
route.data = new RouteMap({});
// Create a '/page' route.
route('{page}', {page: 'home'});
route.ready();
The <Route>
component declaratively maps routes to the component hierarchy. It basically shows/hides a component based on the route attributes you provide:
import {Route} from 'can-route-react';
// Create a basic Home component.
Home () { return (<div>Welcome Home!</div>); }
// The Home component will show when the route has a `page` attribute equal to "home".
<Route data={{page: 'home'}} component={Home} />
An alternate syntax allows you to show/hide a component based on the URL path. This is similar to React Router's Route component.
import {Route} from 'can-route-react';
// The Home component will show when the URL path is "/" or empty string.
<Route path='/' component={Home} />
Pro Tip: While the
path
syntax works just fine, it's not a recommended practice in state-based routing. It tightly couples your component to the URL. If you change your URL scheme, you have to fix every place that uses that URL.
import React from 'react';
import ReactDOM from 'react-dom';
import {Route} from 'can-route-react';
// Handlers for the links
homeClicked () {
route.data.page = 'home';
}
aboutClicked () {
route.data.page = 'about';
}
// Components to pass into the Route component.
Home () => {
return (<div>Welcome Home!'</div>);
};
About ({children}) => {
return (<div>{children}</div>);
};
ReactDOM.render(
<div className='container'>
<div>
<a href='javascript://' onClick={homeClicked}>Home</a>
<a href='javascript://' onClick={aboutClicked}>About</a>
</div>
<div>
{/* React Router compatible syntax is available. See Pro-tips. */}
<Route path='/' component={Home} />
<Route path='/about' component={About} >
{/* This inner text will show because the About component uses `children`. */}
Welcome to the About page!
</Route>
</div>
</div>,
document.querySelector('[root=true]')
);
Do npm install
or run yarn
in the root directory. Start an http-server
and open the root directory.
0.1.0
- The <Route>
component can render children if the routed component uses {children}
in its content.
0.0.2
- Created the <Route>
component.