bai3/note

dva-api

Opened this issue · 0 comments

bai3 commented

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()方法,用取消数据订阅