dva-api
Opened this issue · 0 comments
Api
输出文件
dva
默认输出文件
dva/router
默认输出react-router接口,react-router-redux的接口通过属性routerRedux输出
比如
import { Router, Route, routerRedux } from 'dva/router'
dav/fetch
异步请求库,不和dva强绑定,可以选择任意的请求库
dva/saga
输出redux-sage的接口,主要用于用例的编写
dva/dynamic
解决组件动态加载问题的util方法。
比如:
import dynamci from 'dva/dynamic'
const UserPageComponent = dynamic({
app,
model: ()=> [
import('./models/users')
],
component: () => import('./routes/UserPage')
})
opts包含
- app: dva实例,加载models时需要
- models:返回Promise数组的函数,Promise返回dva model
- component:返回Promise的函数,Promise返回React Component
dva API
app = dav(opts)
创建应用,返回dva实例(dva支持多实例)
opts包含
- history: 指定给路由用的history,默认是hashHistory
- initialState: 指定初始数据,优先级高于model中的state,默认是{}
如果要配置history为browserHistory,可以这样
import createHistory from 'history/createBrowserHistory';
const app = dva({
history: createHistory(),
})
app.use(hooks)
配置hooks或者注册插件
比如注册dva-loading插件
import createloading from 'dva-loading'
app.use(createloading(opts));
onError((err,dispatch) => {})
effect执行错误或subscription通过done主动抛错时触发,可用于管理全局出错状态。
注意:subscription并没有加try... catch ,所以有错误时需通过第二个参数done主动抛错。例子:
app.model({
subscription:{
setup({dispatch},done){
done(e)
},
}
})
如果我们用antd,那么最简单的全局错误处理通常会这么做:
import { message } from 'antd';
const app = dva({
message.error(e.message)
})
onAction(fn | fn[])
在action被dispatch时触发,用于注册redux中间件。支持函数或函数数组格式
例如我们要通过redux-logger打印日志:
import createLogger from 'redux-logger'
const app = dva({
onAction: createLogger(oprs)
})
onStateChange(fu)
state改变时触发,可用于同步state到localStorage,服务器端等
onReducer(fn)
封装reducer执行,比如借助redux-undo实现redo-undo
import undoable from 'redux-undo';
const app = dva({
onReducer: reducer => {
return (state,action) => {
const undoOpts = {};
const newState = undoable(reducer, undoOpts)(state.action);
return {...newState, routing: newState.present.routing};
}
}
})
onEffect(fn)
封装effect执行,比如dva-loading基于此实现了自动处理loading状态
onHmr(fn)
热替换先关
extraReducers
指定额外的reducer,比如redux-form需要指定额外的form reducer
import { reducer as formReducer } from 'redux-form'
const app = dva({
extraReducers: {
form: formReducer
}
})
extraEnhancers
指定额外的StoreEnhancer,比如结合redux-persist使用
import { persistStore, autoRehydrate } from 'redux-persist'
const app = dva({
extraEnhancers: [autoRehydrate()],
})
persistStore(app._store);
app.model(model)
注册model
app.router(({ history,app }) => RouterConfig)
注册路由表
import { Router, Route } from 'dva/router'
app.router(({history}) => {
return (
<Router history={history}>
<Route path="/" component={App}>
<Route>
)
})
app.start
启动应用,selector可选,如果没有selector参数,会返回一个返回JSX元素的函数。
app.start('#root')
Model
model是dva最重要的概念
app.model({
namespace: 'todo',
state: [],
reducers: {
add(state, { payload: todo}){
return [...state,todo]
},
},
effects: {
*save({ paylaod:todo },{ put, call}){
yield call(saveTodoToServer, todo);
yield put({ type: 'add', payload: todo });
},
},
subscriptions: {
setup({history, dispatch}){
return history.listen(({pathname}) => {
if(pathname === '/'){
dispatch({type: 'load'});
}
})
}
}
})
model包含五个属性
namespace
model的命名空间,同时也是他在全局state上的属性,只能用字符串,不支持通过.方式创建多层命名空间。
state
初始化,优先级低于传给dva()的opts.initialState
const app = dva({
initialState: {count: 1}
});
app.model({
namespace: 'count',
state: 0
})
此时,在app.start()后state.count为1
reducers
以key/value格式定义reducer,用于处理同步操作,唯一可以修改state的地方。由action触发。
格式为(state, action) => newState 或 [(state, action) => newState,enhancer]
effects
以key/value格式定义effect,用于处理异步操作和业务逻辑,不直接修改state。由action触发,可以触发action,可以和服务器交互,可以获取全局state的数据。
格式 *(action, effects) => void
或 [*(action, effects) => void, { type }]
type类型有
- takeEvery
- takelatest
- throttle
- watcher
subscriptions
以key/value 格式定义subscription。subscription是订阅,用于订阅一个数据源。然后根据需要dispatch相应的action。在app.start()时被执行,数据源可以是当前的时间、服务器的websocket连接、keyboard输入等
格式为 ({ dispatch, history },done) =>unlistenFunction
注意:如果要是用app.unmodel(),subscription必须返回unlisten()方法,用取消数据订阅