Add React Epic to React Counter App

First, to understand how React Epic works. I will tell you to forget everything about React, got a blank mind first then start to think. In a pure logic, this is how we define a state machine work:

let counter = 0

let increase = (state, action = 1) => state + action
let decrease = (state, action = 1) => state - action
let reset = (state, action) => 0

But this program cannot run because it doesn't have anything to bind with it. The easiest way is to bind to the console:

function bind(state, reducers) {
  function render() {
    console.log(state)
  }

  function setState(func) {
    state = func(state)
    render(state)
  }

  const ui = Object.keys(reducers).reduce(
    (all, name) =>
      Object.assign(all, {
        [name](action) {
          setState(state => reducers[name](state, action))
        }
      }),
    {}
  )

  return ui
}

So when we run the program, it will log out the result:

But then you will find this is not enough. For example, when you call an ajax. How can you put an ajax into setState?

Of course, we can but this seems to not very attractive, there will be some cases that you cannot cover if using thunk only. You need something more consistency and powerful than this. So we come up with another solution: RxJS

To make it easier for you to bind pure logic into RxJS, i provide you with a lift operator. The following lines will demonstrate how it works:

So the increase, decrease, reset functions will be declare like this:

If you're familiar with RxJS, you can even do it better:

Here is how we define the render function:

And how we call the setState:

Reference:

  • For more information about how to use the lift operator, consider reading: Lift Operator

  • For more information about how to declare a function and make a function call in RxJS, consider reading: Exection Context in RxJS

After this, you may wonder how do we subscribe the values from ReactDOM? The most easy way is:

Store and DI

In the most cases you will only need to put the logic at the same place and then connect it with your component using HOC.

To do that, first we need to create the store.

And then define the app logic:

Create a provider for your whole app:

And then connect with the component using WithRx:

Last updated

Was this helpful?