shineYao

dva-counter

dva实例Counter

import dva, { connect } from 'dva';
import { Router, Route } from 'dva/router';
import styles from './index.less';

const app = dva();

function XX() {
  this.events = {};
}

XX.prototype.addListener = function(event, listener) {
  if(!this.events.hasOwnProperty(event)) {
    this.events[event] = listener;
  }
}

XX.prototype.trigger = function(event) {
  if(this.events.hasOwnProperty(event)) {
    (this.events[event])()
  }
}

const xx = new XX();

app.model({
  namespace: 'count',
  state: {
    record: 0,
    current: 0,
  },
  reducers: {
    add(state) {
      const newCurrent = state.current + 1;
      return {
        ...state,
        record: newCurrent > state.record ? newCurrent : state.record,
        current: newCurrent
      }
    },
    minus(state) {
      return {
        ...state, 
        current: state.current - 1
      };
    },
  },
  subscriptions: {
    clickWatcher({dispatch}) {
      xx.addListener('click', () => {dispatch({type: 'minus'})})
    }
  },
  effects: {
    *add(action, {call, put}) {
      yield call(delay, 1000);
      yield put({type: 'minus'});
    }
  }
});

const SubButton = () => {
  return (
    <button onClick={() => xx.trigger('click')}>subButton</button>
  )
}

const CountApp = ({count, dispatch}) => {
  return (
    <div className={styles.normal}>
      <div className={styles.record}>Highest Record: {count.record}</div>
      <div className={styles.current}>{count.current}</div>
      <div className={styles.button}>
        <button onClick={() => { dispatch({type: 'count/add'}); }}>+</button>
      </div>
      <SubButton />
    </div>
  )
}

function mapStateToProps(state) {
  return {
    count: state.count
  };
}

const HomePage = connect(mapStateToProps)(CountApp);

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

app.start('#root');

// -------------
// Helpers

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

.normal {
  width: 200px;
  margin: 100px auto;
  padding: 20px;
  border: 1px solid #ccc;
  box-shadow: 0 0 20px #ccc;
}

.record {
  border-bottom: 1px solid #ccc;
  padding-bottom: 8px;
  color: #ccc;
}

.current {
  text-align: center;
  font-size: 40px;
  padding: 40px 0;
}

.button {
  text-align: center;
  button {
    width: 100px;
    height: 40px;
    background: #aaa;
    color: #fff;
  }
}

posted on 2017-11-28 23:27  shineYao  阅读(176)  评论(0编辑  收藏  举报

导航