开发中出现的问题
- dva可以视为react / react-router / redux / redux-saga 的一个语法糖. 但是来回切换UI / model 还是太麻烦. 想把逻辑简化后写在UI上.
- restful api请求逻辑如果写在effects上太复杂, 希望能有一套统一管理effects的方法.
试试dva-plugin-common
项目地址
安装
- yarn add dva-plugin-common
- npm install dva-plugin --save
使用方法
- 引入hooks
单独使用dva
import { createHooks } from 'dva-plugin-common'
let app = dva({
...createHooks()
})
使用umi
import { createHooks } from 'dva-plugin-common'
export const config = () => {
return {
...createHooks()
}
}
- 引入mapDispatchToProps
import { createMapDispatchToProps } from 'dva-plugin-common'
import { connect } from 'dva'
function Test(){
return <div>Hello</div>
}
const mapDispatchToProps = createMapDispatchToProps('test')
const mapStateToProps = ({ test }) => ({ ...test })
export default connect(mapStateToProps,mapDispatchToProps)(Test)
- 该mapDispatchToProps提供了一个updateState方法, 类似于react的setState
updateState((state) => {
return {
...state,
a:{
b:123
}
}
})
和一个getAsyncData方法, 用于获取restful api的数据, 同步到redux. (需要继承model之后可以使用)
const response = getAsyncData({
namespace: 'test',
url: '/api/getUsers',
options: {
method: 'GET'
},
save: 'users'
})
- 继承model
import { modelExtend } from 'dva-plugin-common'
export default modelExtend({
namespace: 'test',
state: { a: 1 }
})
使用说明
- hooks为必须引入. hooks提供了updateState这个reducer, 和一个request这个extraReducer. updateState同上述说明, 用于提供一个和setState相似的修改redux的方法; request是提供给getAsyncData这个effect使用, 用于保存一个api请求的列表. 可以用于绑定在各种UI组件库的spin组件上.
- createMapDispatchToProps为必须引入. 为UI上提供调用了updateState这个reducer的方法, 和调用getAsyncData这个effect的方法. 同时也提供原生dispatch方法. 允许增加其他dispatch方法, 详见api列表.
- modelExtend为可选引入. 继承了该model之后可以调用getAsyncData这个effect. 如果不继承则无法调用.
- getAsyncData可以用于获取restful api接口数据; 请求的超时处理; 请求的错误处理; 返回值的存储; 和请求列表的保存.
API
createHooks
暂无参数
const hooks = createHooks();
createMapDispatchToProps
| params |
type |
usage |
vital |
| namespace |
string |
dva的namespace |
必选 |
| extraMapDispatchToProps |
function |
其他的mapDispatchToProps |
api同mapDispatchToProps |
const namespace = 'test'
const mapDispatchToProps = createMapDispatchToProps(namespace)
modelExtend
| params |
type |
usage |
vital |
| defaultParams |
object |
该model的默认参数, 详见defaultParams |
非必选 |
| model |
object |
dva的model, 详见dva model的设置 |
必选 |
const model = {
namespace: 'test',
state: { a: 1 },
subscription: {},
reducers: {},
effects: {}
}
const enhanceModelWithoutDefaultParams = modelExtend(model);
const defaultParams = {
TIMEOUT_SEC: 5 * 1000,
MSG_DURATION: 2,
ERR_DEFINE: ({ status }) => status !== true,
SUCC_MSG: ({ respDesc }) => `请求成功: ${respDesc}`,
ERR_MSG: ({ respDesc }) => `请求失败: ${respDesc}`,
}
const enhanceModelWithDefaultParams = modelExntend(defaultParams,model)
defaultParams
| params |
type |
usage |
vital |
| TIMEOUT_SEC |
number |
默认的请求超时时间, 单位为毫秒. 默认10*1000 |
非必选 |
| MSG_DURATION |
number |
默认的成功或错误信息的展示市场, 单位为秒, 默认2 |
非必选 |
| ERR_DEFINE |
function(response) |
非http错误的其他业务错误的定义, 比如response.status===false之类 |
非必选 |
| SUCC_MSG |
function(response) |
请求成功后展示的提示信息内容的定义, 比如response.message |
非必选 |
| ERR_MSG |
function(response) |
请求失败后展示的提示信息内容的定义, 比如response.message |
非必选 |
updateState
| params |
type |
usage |
vital |
| callback |
function(state) |
用于修改redux的某个namespace键值 |
必选 |
getAsyncData
| params |
type |
usage |
vital |
| service |
object |
异步请求的service信息 |
必选 |
| data |
object |
异步请求的request.body信息 |
非必选 |
const response = await getAsyncData(services.updateUsers, data);
console.log(response)
service
| params |
type |
usage |
vital |
| namespace |
string |
redux的namespace键值 |
必选 |
| url |
string |
请求的url地址, 支持以{}为包裹的模板值, 比如url='/api/getPageNum/{pagenum}', data={pagenum:1, pagesize: 10}. 发送是url会被替换成'/api/getPageNum/1', data会被替换成{pagesize: 10} |
必选 |
| options |
object |
请求的options信息, 同fetch |
必选 |
| timeoutSec |
number, false |
同defaultParams的TIMEOUT_SEC. 未空时获取defaultParams的值. 为false是无超时控制 |
非必选 |
| errDefine |
function(response),true |
同defaultParams的ERR_DEFINE, 为空时没有定义.为true时获取defaultParams的值 |
非必选 |
| succMsg |
function(response),true |
同defaultParams的SUCC_MSG, 为空时没有定义,为true是获取defaultParams的值 |
非必选 |
| errMsg |
function(response),true |
同defaultParams的ERR_MSG, 为空时没有定义,为true是获取defaultParams的值 |
非必选 |
| save |
function(state, response), string |
在存储到redux之前对返回值做处理. 为string时, 不对response做处理, 整体存储在redux.namespace[save]下. 如果为function时, 方法的返回值为redux.namespace. 为空时不保存 |
非必选 |
export const functionSave = {
namespace: 'test',
url: '/users',
options: {
method: 'GET'
},
save: (state, response) => ({ ...state, functionSave: { id: response.result[0].id } })
}