Hello World

We're going to build an example that'll get you familiar with the Navigation router's data-first approach. The example will have two scenes or pages. One scene will display a Hyperlink that says 'Hello'. Clicking this Hyperlink will navigate you to the second scene displaying the text 'World' inside a div. We'll pass across a number that we'll use to set the div's font-size.

After following the Setup instructions, we'll add two States to the StateNavigator array that represent the scenes in our example. There'll be one State for the 'hello' scene and another for the 'world' scene. With other routers, you'd have to configure your routes at this stage. With the Navigation router, you can leave your routes until the end. All routes apart from the empty route, that is, which we'll assign to the 'hello' State so that it's active when the page first loads.

const stateNavigator = new StateNavigator([
  {key: 'hello', route: ''},
  {key: 'world'}
]);

We'll create the scene for the 'hello' State. It renders a Hyperlink that navigates to the 'world' scene. We'll let the NavigationLink component handle the rendering. It has a stateKey prop that holds the key of the destination State. The 'world' scene renders the text 'World' inside a div. In the next section we'll size this text based on a number passed from the 'hello' scene.

import {NavigationLink} from 'navigation-react';

const Hello = () => (
  <NavigationLink stateKey="world">
    Hello
  </NavigationLink>
);

const World = () => <div>World</div>;

We'll wrap each scene inside a SceneView component and assign the State's key to the active prop. The SceneView component only renders its scene when the associated State becomes active. The 'home' scene is activated when the site first loads because we gave it the empty route.

import {SceneView} from 'navigation-react';

<NavigationHandler stateNavigator={stateNavigator}>
  <SceneView active="hello"><Hello /></SceneView>
  <SceneView active="world"><World /></SceneView>
</NavigationHandler>

Data First

We'll change the Hyperlink to pass across a number that will become the font-size of the div. With other routers, we'd have to decide now whether to pass it as a route or query string parameter. With the Navigation router, we can leave this decision to the end. The NavigationLink component has a navigationData prop that holds the data to pass to the destination State. We'll pass the number 20 as the size to the 'world' State.

const Hello = () => (
  <NavigationLink stateKey="world" navigationData={{size: 20}}>
    Hello
  </NavigationLink>
);

We'll change the World component to retrieve the data from the NavigationContext and use the number to set the div's font-size.

import {NavigationContext} from 'navigation-react';

const World = () => {
  const {data} = useContext(NavigationContext);
  return <div style={{fontSize: data.size}}>World</div>;
};

Routes Last

Our example's up and running. But, because we haven't set a route for the 'world' State, the Navigation router auto-generates the Url. It turns size into a query string parameter and adds trailing digits to track the type of the size parameter. We'll tidy up the Url by making size a route parameter and defaulting its type to 'number'. The rest of the code remains unchanged because the data we're passing around hasn't changed.

const stateNavigator = new StateNavigator([
  {key: 'hello', route: ''},
  {key: 'world', route: '{size}', defaultTypes: {size: 'number'}}
]);

Ta-dah!

With other routers, your Urls are set upfront and changes can ripple throughout your codebase. With the Navigation router, Urls are just a string representation of your typed data. You can safely update routes or switch between query and route parameters without impacting your code.