Rocon Concepts
Rocon is a router library with ultimate type safety. In order to understand Rocon, it is important to understand how you define routes with Rocon.
Core concepts of Rocon includes route builders, route records and match objects. This page explains these concepts.
Route Builders
In Rocon, you need to define routes first in order to render contents in response to certain URLs. Routes are defined using route builders.
Each builder represents a simple constituent of a URL. To build routes that represent complex URLs, you need to compose multiple builders by attaching one to another. For example, one Path route builder represents a single segment of pathnames (like /foo
or /bar
). To construct a route for /foo/bar
, you attach a Path route builder for /foo
to another Path route builder for /foo
.
Another example of route builders is Search route builder which represents a single key-value pair in the search query string (?key1=value1&key2=value2
). By composing a Path route builder and a Search route builder, you can define a URL like /foo?key=value
.
When defining routes using route builders, an action may be defined for each route. An action is a function that returns a React element. With the useRoutes hook, you can resolve the current location against a provided route builder, execute the action that corresponds to the current location and render the result of that action.
Example
// define a /foo route using a Path route builder
const toplevelBuilder = Rocon.Path()
.route("foo");
// attach another Path route builder to get a /foo/bar route
const fooRouteBuilder = toplevel._.foo
.attach(Rocon.Path())
.routes({
bar: {
// define contents that are rendered
// when /foo/bar is visited
action: () => <p>This is /foo/bar</p>
}
});
Route Records
Routes defined by route builders are represented as objectes called route records. A route record has type ReactRouteRecord<Match> where Match
is the type of match object associated to this route record (described later).
A route record is needed when you want to attach another route builder to it or you want to navigate to that route. “Attaching one route builder to another builder” in the above explanation is not perfectly accurate; actually you attach a route builder to a route record (defined using another builder).
Route records can be retrieved from the route builder that defines them. Route builders other than Path route builder define only one route and it can be retrieved by builder.route
. On the other hand, a Path route builder can define multiple routes, including special routes called an exact route and an any route. To retrieve a route record from a Path route builder, you can do builder._.foo
for named routes, builder.exactRoute
for exact routes andbuilder.anyRoute
for any routes.
Match Objects
A match object contains extra information needed for a route record to point to a concreate URL.
For example, if you defined a route for /foo?key=xxxx
, the xxxx
part can be any string in concrete URLs. When the current URL matches this route, the actual value of xxxx
is provided in a match object (e.g. { key: "somevalue" }
).
A match object is provided as an argument when the action associated to that route is executed. In contrast, you have to provide a match object when you navigate to a route that requires a corresponding match object.
Example
// define a /foo route using a Path route builder
const toplevelBuilder = Rocon.Path()
.route("foo");
// attach a Search route builder to get a /foo?key=xxxx route
const fooRouteBuilder = toplevel._.foo
.attach(Rocon.Search("key"))
// this route's action receives a match object containing 'key'
.action(({ key }) => <p>The value of key is {key}</p>);
// ...
// to navigate to /foo?key=xxxx, you need to
// provide the value of 'key'
<Link route={fooRouteBuilder.route} match={{ key: "12345" }}>
Link to /foo?key=12345
</Link>