Routing Context

Along with the latest request, matchers like mount() and route() have access to an object called the Context. By default, the Context is just an empty object, but you can set it to anything you’d like.

There are two ways to set the Context: you can pass a prop to your <Router> element, or you can use the withContext() matcher. In fact, you can use both methods in the same app.

withContext()

The withContext() matcher lets you specify the context of its children as a function of the current request and the parent context.

withContext((request, parentContext) => childContext, children)

For example, you could use withContext() to add a rootpath property to the context of its child matcher. This is useful for giving you a “base” path from which you can make your links.

withContext(
  (request, parentContext) => ({
    ...parentContext,
    rootpath: request.mountpath,
  }),
  children
)

Because the withContext() function specifies context as a function of its parents’ state, you can use it as often as you want. However, you’ll need to be a little more careful about use of the context prop.

The context prop

The <Router> component accepts a context prop, which you can use to set the Context for the routes that you’ve passed in. This is useful for passing in data and functions that you might want to use in your routes.

<Router
  routes={routes}
  context={{
    api,
    currentUser,
    isStatic,
  }}
/>

There’s one thing to be careful about when passing Context this way: every time the context changes, your entire Route will need to be recomputed. This means re-running your getView() functions, getData() functions, and any other getters — even if they don’t reference the Context.

There is one saving grace: <Router> uses a shallow equality check to decide if context has changed, so you can still specify context as a plain old JavaScript object (like in the above example) — so long as each of the object’s values remain reference-equal. But be careful - if you’re fetching data in your routes, then getting your context prop wrong can result in a lot of unnecessary network activity.

With this in mind though, Context is an incredibly useful tool. You can:

  • Provide different APIs to routes in production and test environments.
  • Create reusable routes whose links depend on where the root route is mounted.
  • Switch the active route based on a user’s authentication status.

Speaking of Authentication — we’ll use Context in the next guide to implement authenticated routes. I’ll see you there!