前言
这篇简单介绍一下dva
为什么要有dva
在使用react
开发时,进行react
和router
和redux
的配置比较繁琐,而dva
考虑到这个问题,而对它们进行了一层封装,从而让开发变得更加方便。
官方介绍:dva 是一个基于 redux 和 redux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-router 和 fetch,所以也可以理解为一个轻量级的应用框架。
使用方法
在index.tsx中创建dva
应用,并且配置redux
和router
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import './style/index.css'; import dva from "dva"; import counterModel from "./models/counter" import usersModel from "./models/user" import { createBrowserHistory } from "history" import routerConfig from "./router/index";
const app = dva({ history : createBrowserHistory() });
app.model(counterModel); app.model(usersModel);
app.router(routerConfig);
app.start("#root");
|
在model
中可以进行一些redux
相关的配置,可以理解这里整合了redux的action、reducer、redux-saga 副作用处理等等东西,配置如下
- namespace:命名空间,该属性是一个字符串,字符串的值,会被作为仓库中的属性保存
- state:该模型的默认状态
- reducers: 该属性配置为一个对象,对象中的每个方法就是一个reducer,dva约定,方法的名字,就是匹配的action类型
- effects: 处理副作用,底层是使用redux-saga实现的,该属性配置为一个对象,对象中的每个方法均处理一个副作用,方法的名字,就是匹配的action类型。
- 函数的参数1:action
- 参数2:封装好的saga/effects对象
- subscriptions:配置为一个对象,该对象中可以写任意数量任意名称的属性,每个属性是一个函数,这些函数会在模型加入到仓库中后立即运行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| export default { namespace: "counter", state: 0, reducers: { increase(state) { return state + 1; }, decrease(state) { return state - 1; }, add(state, { payload }) { return state + payload; } }, effects: { *asyncIncrease(action, { call, put }) { yield call(delay, 1000); yield put({ type: "increase" }) }, *asyncDecrease(action, { call, put }) { yield call(delay, 1000); yield put({ type: "decrease" }) } }, subscriptions: { onresize({ dispatch }) { window.onresize = () => { console.log("窗口尺寸变化了") } } } }
function delay(duration) { return new Promise(resolve => { setTimeout(() => { resolve() }, duration); }) }
|
然后是路由相关的配置,路由的话,dva
没有做太多东西,基本和原生一致,但是你可以很方便的同步路由到redux
,使用下面的方法即可
- 在调用dva函数时,配置history对象
- 使用ConnectedRouter提供路由上下文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React from 'react' import Counter from "../component/Counter" import App from "../component/App/App"; import Home from "../component/Home"; import { routerRedux, NavLink, Route, Switch } from "dva/router"
export default function ({ history }) { return ( <routerRedux.ConnectedRouter history={history}> <App> <div> <ul> <li> <NavLink to="/">Home</NavLink> </li> <li> <NavLink to="/counter">Counter</NavLink> </li> </ul> <div> <Switch> <Route path="/counter" component={Counter} /> <Route path="/" component={Home} /> </Switch> </div> </div> </App> </routerRedux.ConnectedRouter> ) }
|
效果大概是这样