2017-11-13 19:37:43 +00:00
# Redux-Observable example
## How to use
2017-12-03 04:30:17 +00:00
### Using `create-next-app`
2018-04-03 12:19:05 +00:00
Execute [`create-next-app` ](https://github.com/segmentio/create-next-app ) with [Yarn ](https://yarnpkg.com/lang/en/docs/cli/create/ ) or [npx ](https://github.com/zkat/npx#readme ) to bootstrap the example:
2017-12-03 04:30:17 +00:00
2018-03-14 08:09:46 +00:00
```bash
npx create-next-app --example with-redux-observable with-redux-observable-app
# or
yarn create next-app --example with-redux-observable with-redux-observable-app
2017-12-03 04:30:17 +00:00
```
### Download manually
2018-07-11 21:56:15 +00:00
Download the example:
2017-11-13 19:37:43 +00:00
```bash
2017-12-07 02:12:42 +00:00
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-redux-observable
2017-11-13 19:37:43 +00:00
cd with-redux-observable
```
Install it and run:
```bash
npm install
npm run dev
2018-04-03 12:19:05 +00:00
# or
yarn
yarn dev
2017-11-13 19:37:43 +00:00
```
### The idea behind the example
2018-02-04 11:56:32 +00:00
This example is a page that renders information about Star-Wars characters. It
fetches new character every 3 seconds having the initial character fetched on
a server.
2017-11-13 19:37:43 +00:00
Example also uses `redux-logger` to log every action.
![demo page ](demo.png )
2018-02-04 11:56:32 +00:00
The main problem with integrating Redux, Redux-Observable and Next.js is
probably making initial requests on a server. That's because, the
`getInitialProps` hook runs on the server-side before epics have been made available by just dispatching actions.
However, we can access and execute epics directly. In order to do so, we need to
2018-07-21 23:37:59 +00:00
pass them an Observable of an action together with StateObservable and they will return an Observable:
2018-02-04 11:56:32 +00:00
```js
static async getInitialProps({ store, isServer }) {
2018-07-21 23:37:59 +00:00
const state$ = new StateObservable(new Subject(), store.getState());
2018-02-04 11:56:32 +00:00
const resultAction = await rootEpic(
of(actions.fetchCharacter(isServer)),
2018-07-21 23:37:59 +00:00
state$
2018-02-04 11:56:32 +00:00
).toPromise(); // we need to convert Observable to Promise
store.dispatch(resultAction)};
```
Note: we are not using `AjaxObservable` from the `rxjs` library; as of rxjs
v5.5.6, it will not work on both the server- and client-side. Instead we call
the default export from
2018-07-21 23:37:59 +00:00
[universal-rxjs-ajax ](https://www.npmjs.com/package/universal-rxjs-ajax ) (as
`request` ).
2018-02-04 11:56:32 +00:00
We transform the Observable we get from `ajax` into a Promise in order to await
its resolution. That resolution should be a action (since the epic returns
Observables of actions). We immediately dispatch that action to the store.
This server-side solution allows compatibility with Next. It may not be
something you wish to emulate. In other situations, calling or awaiting epics
directly and passing their result to the store would be an anti-pattern. You
should only trigger epics by dispatching actions. This solution may not
generalise to resolving more complicated sets of actions.
The layout of the redux related functionality is split between:
2017-11-13 19:37:43 +00:00
2018-02-04 11:56:32 +00:00
- actions (in `redux/actions.js` )
- actionTypes (in `redux/actionTypes.js` )
- epics (in `redux/epics.js` )
- reducer (in `redux/reducer.js` )
2017-11-13 19:37:43 +00:00
2018-02-04 11:56:32 +00:00
and organized in `redux/index.js` .
2017-11-13 19:37:43 +00:00
2018-02-04 11:56:32 +00:00
Excepting in those manners discussed above, the configuration is similar the
configuration found in [with-redux example ](https://github.com/zeit/next.js/tree/canary/examples/with-redux )
and [redux-observable docs ](https://redux-observable.js.org/ ).