Rocon Website

Navigation

Navigation means to move from one path to another path. Rocon provides two ways of navigation: the Link component and the useNavigate hook. The Link component is suitable when you want to create an <a> element which, on clicked, navigates to the specified path. The useNavigate hook is for other cases where you have to programatically perform a navigation.

With Rocon, you specify the target of navigation by passing a route record. This is the core of Rocon's type safety; you cannot even create a route record for a path you did not define, so you will never mistakenly specify a nonexistent path.

Using the Link Component

import Rocon, { Link } from "rocon/react";

const toplevelRoutes = Rocon.Path()
  .route("foo", (route) => route.action(() => <p>This is foo</p>))
  .route("bar", (route) => route.action(() => <p>This is bar</p>));

const Menu: React.FC = () => {
  return (
    <ul>
      <li>
        <Link route={toplevelRoutes._.foo}>Go to foo</Link>
      </li>
      <li>
        <Link route={toplevelRoutes._.bar}>Go to bar</Link>
      </li>
    </ul>
  );
};

The above example first defines /foo and /bar. Then it defines a Menu component which consists of links to /foo and /bar. We do not write down raw paths; instead the Link component receives a route record through the route prop. The Link component internally converts the given route record to an actual path.

Using the useNavigate Hook

The useNavigate hook returns a navigate function. It receives a route record and performs a navigation to the given route.

const Menu: React.FC = () => {
  const navigate = useNavigate();
  return (
    <ul>
      <li>
        <button onClick={()=> navigate(toplevelRoutes._.foo)}>
          Go to foo
        </button>
      </li>
      <li>
        <button onClick={()=> navigate(toplevelRoutes._.bar)}>
          Go to bar
        </button>
      </li>
    </ul>
  );
};

There is also a navigate.replace function which performs history.replace instead of history.push.

Providing a Match Object

To navigate to a route which requires a match object, we have to provide a corresponding match object. For useNavigate, pass the match object as a second parameter. For Link, pass it via a match prop.

Of course, TypeScript tracks when a match object is required. Not passing anything, passing an empty object, or setting id to a number instead of a string would all result in a type error.

const toplevelRoutes = Rocon.Path()
  .any("id", {
    action: ({ id }) => <p>Hello, {id}</p>
  });

const Menu: React.FC = ()=> {
  const navigate = useNavigate();
  return (
    <button onClick={()=> {
      navigate(toplevelRoutes.anyRoute, { id: "uhyo" });
    }}>Go to uhyo's page</button>
  );
};