-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[讨论] API 设计 #7
Comments
想到怎么写了。。。 |
还有 saga 实际应用可能不只会用到 takeEvery, takeLatest 两种模式,比如我们有个 saga 用到了 function* watchStartPolling() {
let lastTask
while (true) {
const action = yield race({
start: take(startPolling.getType()),
stop: take(stopPolling.getType()),
})
if (lastTask) {
yield cancel(lastTask)
}
if (action.start) {
lastTask = yield fork(polling)
}
}
} |
@yesmeck saga 新增一个类型,比如 |
其实我是不大喜欢这种配置式的 API,有没有考虑过把 reducer 和 saga 设计成按方法传入(之前提过 reducer 的,subscriptions 不熟暂时不说 )? const reducers = (state, action) {
// blah blah
}
const effects = function* () {
// blah blah
}
app.model({
namespace: 'count',
state: 0,
reducers,
effects,
}); 这样实现起来应该也简单点,而且更灵活,坏处可能就是太灵活。。。 |
恩,太灵活了。。 我希望加一些简单的约定,比如 reducers 和 effects 的 key 是 action 。一方面可以简化部分书写,另外我们之后还会探索下图形化编程,需要做一些静态化的语法分析。这也是为啥没有直接支持 另外,以我目前所了解的信息是,不加配置的默认使用可以满足 80% - 90% 的需求。saga 的 race,以及 reducer enhancer 都属于高级需求,至少在我们这边的项目都还没有用到过。 |
是否可以考虑将 start和render分开,https://github.com/sorrycc/dva/blob/master/src/index.js#L97, 因为考虑到一些应用框架的使用,比如chair,就是直接内置的render方式,大概为: yield this.render('App.jsx', {
runAtServer: false,
context: {
user: {
name: this.user.cname,
},
},
}); 这个时候,可能App.jsx返回的是 <Provider store={store}>
<Routes history={history} />
</Provider> 但是
可能是交给框架执行 |
麻烦问下,在onError 报错中,怎么获取到当前报错代码属于哪个model(namespace)中呢? |
重新思考了下 api 的设计和功能,做了一些调整。欢迎讨论。
API
app = dva(opts?)
opts.onError:
默认throw
出错信息,在effect
和subscription
出错时被调用。app.model(obj)
Takes the following arguments:
namespace:
model state 在全局 state 上所在的 key 值state:
model 的初始值reducers:
同步操作,用于更新数据,由action
触发effects:
异步操作,不直接更新数据,由action
触发,可以 dispatchaction
subscriptions:
异步只读操作,不直接更新数据,可以 dispatchaction
一个完整的例子:
namespace
是 model 在全局 state 上所占的 key,格式为字符串。虽然叫 namespace,但像a.b
并不会被扩展为globalState.a.b
。state
是 plain object 。reducers
对应 redux 的 reducer,格式为 object/array。默认是 object,如果要支持 reducer enhancer,需要写成 array,第二个参数为 reducer enhancer 。例:effects
对应 redux-saga。他有类型,takeEvery
或takeLatest
。默认是takeEvery
,如果想要takeLatest
,可以这样:上面
reducers
和effects
的扩展配置的方式都是通过数组第二项的方式进行配置,参考自babel
。subscriptions 用于订阅数据源,格式为数组,他们会在 domready 时被执行。详见:subscription 及其适用场景。
app.router(({ history }) => [routes])
使用和 ReactRouter 相同的配置,不做封装,可用 jsx 格式,也可用 javascript object 的格式支持动态路由。
详见:react-router/docs
app.start(HTMLElement, opts?)
Opts can contain the following values:
opts.history:
default:hashHistory
opts.middlewares:
default:[]
opts.reducers:
default:{}
opts.hmr:
default:null
opts.history
是给路由用的 history,支持 hashHistory 和 browserHistory 。默认是 hashHistory,如果要换成 browserHistory,可以这样:opts.middlewares
是支持 redux 的 middleware,数组类型。opts.reducers
是提供额外的 reducers,用于支持类似 redux-form 这种插件。opts.hmr
作为用户通常不需要关心。顾名思义是拿来做 Hot Module Replacement 用的,格式为(render, replaceReducer, restartSaga) => {}
,传入用于刷新 component, reducer, saga 的方法,给 HMR 用。(目前只支持 render)HMR 的例子详见 user dashboard,代码有点多,之后会通过 babel 插件的方式让使用无感知。
尚未考虑的点
dva/effects
的调用方式简化connect
的封装 (和 reselect 结合,默认高性能)fetch
的封装The text was updated successfully, but these errors were encountered: