- npm install —save dva dva-loading
声明model,model中有
reducers和effectsconst delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));// 注册 Modelapp.model({namespace: 'count', // 当前model的名称state: {count: 0,num: 77,}, // 当前model的状态reducers: { // 处理同步activeadd(state, active) {const { payload } = active;payload.count += 1;console.log(state, active);return {...state,...payload,}},minus(state, active) {const { payload } = active;payload.count -= 1;console.log(state, active);return {...state,...payload,}},},effects: { // 处理异步active* addAfter1Second(action, { call, put }) {console.log(action);yield call(delay, 10000);yield put({ type: 'add', payload: action.payload });},* minusAfter1Second(action, { call, put }) {console.log(action);yield call(function() {console.log('222')}, 10000);yield put({ type: 'minus', payload: action.payload });},},subscriptions: {setup({ history, dispatch }) {// 监听 history 变化,当进入 `/` 时触发 `load` actionconsole.log(history)return history.listen(({ pathname }) => {console.log(pathname);if (pathname === '/') {dispatch({ type: 'load' });}});},},});
Action 是一个普通 javascript 对象,它是改变 State 的唯一途径。无论是从 UI 事件、网络回调,还是 WebSocket 等数据源所获得的数据,最终都会通过 dispatch 函数调用一个 action,从而改变对应的数据。action 必须带有 type 属性指明具体的行为,其它字段可以自定义,如果要发起一个 action 需要使用 dispatch 函数;需要注意的是 dispatch 是在组件 connect Models以后,通过 props 传入的。
上面那个model就有4个active add,minus,addAfter1Second,minusAfter1Second
dispatch 触发active,dipatcch会触发Reducer函数 Reducer
= (state: S, action: A) => S,会进行状态的合并props.dispatch({type: 'count/add',payload: {count: props.count.count}})
Effect 副作用,底层使用redux-sage做异步流程控制,采用generator机制
- Subscriptions 语义是订阅,用于订阅一个数据源,然后根据条件 dispatch 需要的 action。
- 配置router
- connect Model

import * as React from 'react';import dva, { connect } from 'dva';import createLoading from 'dva-loading'; // dva自动处理loading的插件import {Router, Route, Switch} from 'dva/router'; // dva里嵌套的react-routerconst app = dva();console.log(app._store); // 顶部的 state 数据app.use(createLoading());const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));// 注册 Modelapp.model({namespace: 'count', // 当前model的名称state: {count: 0,num: 77,}, // 当前model的状态reducers: { // 处理同步activeadd(state, active) {const { payload } = active;payload.count += 1;console.log(state, active);return {...state,...payload,}},minus(state, active) {const { payload } = active;payload.count -= 1;console.log(state, active);return {...state,...payload,}},},effects: { // 处理异步active* addAfter1Second(action, { call, put }) {console.log(action);yield call(delay, 10000);yield put({ type: 'add', payload: action.payload });},* minusAfter1Second(action, { call, put }) {console.log(action);yield call(function() {console.log('222')}, 10000);yield put({ type: 'minus', payload: action.payload });},},subscriptions: {setup({ history, dispatch }) {// 监听 history 变化,当进入 `/` 时触发 `load` actionconsole.log(history)return history.listen(({ pathname }) => {console.log(pathname);if (pathname === '/') {dispatch({ type: 'load' });}});},},});// 3. Viewconst Home = connect(count => count)(function(props) {console.log(props)return (<div><h2>{ props.count.count }</h2><h2>{ String(props.loading.global) }</h2><button key="add" onClick={() => { props.dispatch({type: 'count/add',payload: {count: props.count.count}})}}>+</button><button key="minus" onClick={() => { props.dispatch({type: 'count/minus',payload: {count: props.count.count}})}}>-</button><button key="*add" onClick={() => {props.dispatch({type: 'count/addAfter1Second',payload: {count: props.count.count}})}}>+</button><button key="*minus" onClick={() => { props.dispatch({type: 'count/minusAfter1Second',payload: {count: props.count.count}})}}>-</button></div>);});const router = function (arg: any) {return (<Router history={arg!.history}><Switch><Route path="/" exact component={Home} /></Switch></Router>)}app.router(router);app.start('#main');
注意 :dva 可以 支持 HMR,基于 babel-plugin-dva-hmr 实现 components、routes 和 models 的 HMR

generator

