Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/afenton90/koa-react-router

react-router middleware for koa 2.
https://github.com/afenton90/koa-react-router

koa koa2 middleware react react-router

Last synced: about 1 month ago
JSON representation

react-router middleware for koa 2.

Awesome Lists containing this project

README

        

# koa-react-router

koa 2 middleware for React server side rendering and routing with [react-router 5](https://github.com/ReactTraining/react-router).

> Looking for React Router 3 support see [v1](https://github.com/afenton90/koa-react-router/tree/v1.1.2) docs.
Try React Router 5 though it's awesome!

## Usage

To install `koa-react-router`:

```
npm install koa-react-router react react-dom react-router --save
```

> Note: `react` `react-dom` & `react-router` are all `peerDependencies` of `koa-react-router`.

`koa-react-router` can be mounted easily in a koa 2 application like so:

```js
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
import App from './App';
import Container from './containers/PageContainer';

const app = new Koa();

app.use(reactrouter({
App,
onError: (ctx, err) => console.log('I Have failed!!!!'),
onRedirect: (ctx, redirect) => console.log('I have redirected!'),
onRender: (ctx) => ({ Container })
}));
```

## API

`koa-react-router` requires the following parameters:

### `App`

The `App` config prop should be a react component that contains one or more React Router 4 `Route` components to be rendered.
For example:
```jsx
// App.js
import React from 'react';
import { Route } from 'react-router';
import Home from '../containers/Home';
import Article from '../containers/Article';

const App = () =>


This is my App!




;

// index.js
// ...imports
import App from './App';

// ... koa app setup
app.use(reactrouter({
App,
// Other callbacks
}));
```
### `preRender`

Callback function called before rendering `App`.
This callback can either be a normal function which returns a valid component or it can return a `Promise` which then resolves and returns a valid component.
The function accepts the following parameters:

* `component` - The `StaticRouter` wrapped around the `App`.

> This callback could be used to wrap the `component` with any other higher-order component before it gets rendered

### `onError`

Callback function called when an error occurs whilst route matching or rendering.
The function accepts the following parameters:

* `ctx` - The Koa [`Context`](http://koajs.com/#context) object.
* `err` - The error that was caught when matching routes.

### `onRedirect`

Callback function called if a `Redirect` route is matched.
The function accepts the following parameters:

* `ctx` - The Koa [`Context`](http://koajs.com/#context) object.
* `redirectUrl` - The url to redirect to.

### `onRender`

Callback function called before sending a response to the client.
This function must be supplied, and must return an object that contains the following property:

#### `Container`
This should be a React component that wraps around the rendered route.
Typically this will be the template for the page, however this is not mandatory.
As such this component is rendered using `renderToStaticMarkup`.
The component must accept the `children` prop and insert it when rendered.
For example:

```jsx
// ./containers/Container
import React from 'react';

const Container = (props) =>


Hello Container



{props.children}


;

export default Container;
```

This would then be supplied to `koa-react-router` via the `onRender` callback like so:

```js
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
import App from './App';
import Container from './containers/Container';

const app = new Koa();

app.use(reactrouter({
App,
onRender: (ctx) => ({ Container })
}));
```

As well as the `Container` property this callback can optionally return:

#### `containerRenderer`

Optional function for handling the rendering of a container component.
This function has one argument which is `view`. This argument is the currently rendered view of the app.
This function may be used if some custom props need to be injected into the container component, such as an initial Redux state.
This function should be used instead of the `Container` property when returning from `onRender`.
For example you may want to render the container as follows:

```js
// index.js
import Koa from 'koa';
import reactrouter from 'koa-react-router';
// ...other imports

const app = new Koa();

const state = // Create state.

app.use(reactrouter({
App,
onRender: (ctx) => ({
containerRenderer: (view) =>





hello container





})
}));
```

The final page render would look something like:

```html


//State config


hello container





```

### `id`

Optional id for React to use as the base of the app. **Default**: `app`

In order for React to re-hydrate the DOM on the client it needs to know where it should attach itself. In a previous version of `koa-react-router` this was not [possible](https://github.com/afenton90/koa-react-router/issues/11). This property allows you to add a custom root id to the DOM. For example, if you set this to `root`, the output would look something like.

```html


//State config





```

## Router Context
React Router 4 added support for a [static router context](https://reacttraining.com/react-router/web/example/static-router) this context can be used in your application, to pass values from your router to other middleware and drive behaviour for routes.
`koa-react-router` makes this context available on the koa `ctx` in the following location:
```js
ctx.state.routerContext;
```

One example of using this context is setting a `status` in the route context so a later middleware can set that as this response code.
The common use case of status is already taken care of. So if one of your routes sets a `status` prop whilst rendering that will be set as the response status See [Not found](#what-do-i-do-with-routes-that-are-not-found-) in the FAQ section for an example.
Use the `routerContext` for whatever you want in your app, some common recipes will be added to this repo at a later date.

## FAQ

This release includes some deprecated props. As React Router has come with some major changes so has `koa-react-router`.

### No more routes prop ?
The `routes` prop has gone in favour of the `App` config prop. Where you would have passed in your static routes before you can now pass in your `App` component that contains the React Router routes. For example:

```jsx
// App.js
import React from 'react';
import { Route } from 'react-router';
import Home from '../containers/Home';
import Article from '../containers/Article';

const App = () =>


This is my App!




;
```
React Router 4 gives you the flexibility to define your routes wherever you want in your app, and so does `koa-react-router`.

### What do I do with routes that are not found ?
The previous version of `koa-react-router` supported a `onNotFound` callback. This has been deprecated in favour of defining a `status` prop on the React Router static context and using a `Switch` component in your app. For example, our `App` component may be written as:

```jsx
import React from 'react';
import { Route, Switch } from 'react-router';
import Home from '../containers/Home';
import Article from '../containers/Article';

const NotFound = ({ status }) =>
{
if (staticContext) staticContext.status = status;
return

This route has not been found Soz!
;
}}
/>;

const App = () =>


This is my App!







;
```

If not other routes are matched the `NotFound` component will be rendered, and `koa-react-router` will set the response code status.