Edit in JSFiddle

const { connect } = dva;
const { Router, Route } = dva.router;

const delay = timeout => {
  return new Promise(resolve => {
    setTimeout(resolve, timeout);
  });
};

// 1. Initialize
const app = dva();

// 2. Model
app.model({
  namespace: 'count',
  state: 0,
  effects: {
    *add(action, { put, call }) {
      yield call(delay, 1000);
      yield put({ type: 'minus' });
    },
  },
  reducers: {
    add(count) { return count + 1 },
    minus(count) { return count - 1 },
  },
});

// 3. View
const App = connect(({ count }) => ({
  count
}))(function(props) {
  return (
    <div>
      <h2>{ props.count }</h2>
      <button key="add" onClick={() => { props.dispatch({type: 'count/add'})}}>+</button>
      <button key="minus" onClick={() => { props.dispatch({type: 'count/minus'})}}>-</button>
    </div>
  );
});

// 4. Router
app.router(({ history }) =>
  <Router history={history}>
    <Route path="/" component={App} />
  </Router>
);

// 5. Start
app.start('#root');
<script src="https://npmcdn.com/react@15.2.0/dist/react.min.js"></script>
<script src="https://npmcdn.com/react-dom@15.2.0/dist/react-dom.min.js"></script>
<script src="https://npmcdn.com/dva@1.0.0/dist/dva-min.js"></script>
<script src="https://npmcdn.com/dva@1.0.0/dist/router-min.js"></script>
<script src="https://npmcdn.com/babel-polyfill@6.9.1/dist/polyfill.min.js"></script>

<div id="root"></div>