- npm install —save dva dva-loading
声明model,model中有
reducers
和effects
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
// 注册 Model
app.model({
namespace: 'count', // 当前model的名称
state: {
count: 0,
num: 77,
}, // 当前model的状态
reducers: { // 处理同步active
add(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` action
console.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-router
const app = dva();
console.log(app._store); // 顶部的 state 数据
app.use(createLoading());
const delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
// 注册 Model
app.model({
namespace: 'count', // 当前model的名称
state: {
count: 0,
num: 77,
}, // 当前model的状态
reducers: { // 处理同步active
add(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` action
console.log(history)
return history.listen(
({ pathname }) => {
console.log(pathname);
if (pathname === '/') {
dispatch({ type: 'load' });
}
}
);
},
},
});
// 3. View
const 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