-
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
dva 介绍 #1
Comments
被 redux 搞得死去活来的,简直是福音啊,太简洁、优雅啦,大赞!!! btw,今天无意间在推上看到一老外转发了下,以为还是老外写的,没想到是支付宝的同学,👍 |
期待effects的扩展 |
支付宝生产环境有在使用这套架构么? |
reducer 的写法是不是可以设计成这样: const reducer = (state, { type, payload }) => {
switch (type) {
case 'products/query':
return { ...state, loading: true, };
case 'products/query/success':
return { ...state, loading: false, list: payload };
default
return state;
}
}
app.model({
reducer
}) 这样就可以对 reducer 应用一些高阶方法。 |
好评,写了几个demo就一个问题,model只能用 |
不用 |
@yesmeck reducer 高阶用法的具体场景目前是否也就 |
我们项目中用了不少,比如我们会把多个 reducer 逻辑类似的部分抽成一个高阶方法,去修饰原有的 reducer,还有能让 reducer 在路由变化的时候重置状态的高阶方法,还有这个 https://github.com/erikras/multireducer |
@Tinker404 感觉分开声明 model 会更清楚,增加删除都比较容易。我会这么写: app.model(require('../models/a'));
app.model(require('../models/b')); |
@JimmyLv 个人倾向于不用 actionCreator,而是直接 |
@yesmeck ok,我再考虑下看。
感觉这个场景通过在 |
这样的话,需要重置的 reducer 就要每个都写一下重置的逻辑,用高阶方法的话我们现在只要这样: combineReducers({
products: composeReducers({ // composeReducers 的实现见下面
recycle(LOCATION_CHANGE, initialState), // recycle 用来在路由变化时重置状态
products
})
}) 还有一个场景就是我说的抽取不同 reducer 的相同逻辑。比如有一个产品列表和一个用户列表,它们的 reducer 是这样的: // reducers/products.js
const reducer = (state, { type, action}) => {
switch (type) {
case 'products/FETCH_SUCCESS':
return {
...state,
loading: false,
list: payload
}
default:
return state
}
} // reducers/users.js
const reducer = (state, { type, payload}) => {
switch (type) {
case 'users/FETCH_SUCCESS':
return {
...state,
loading: false,
list: payload
}
default:
return state
}
} 这里两个 reducer 几乎是一样的,我们就抽出来写一个 list reducer: const list = (actionType) => {
return (state, { type, payload }) => {
switch (type) {
case actionType:
return {
...state,
loading: false,
list: payload
}
break;
default:
return state
}
}
} 然后我们实现一个 function composeReducers(...reducers) {
return (state, action) => {
if (reducers.length === 0) {
return state
}
const last = reducers[reducers.length - 1]
const rest = reducers.slice(0, -1)
return rest.reduceRight((enhanced, reducer) => reducer(enhanced, action), last(state, action))
}
} 这样,产品列表和用户列表的 reducer 就变成这样了: // reducers/products.js
const reducer = (state, { type, payload}) => {
// 其他逻辑
}
export default composeReducer(reducer, list('products/FETCH_SUCCESS')) // reducers/users.js
const reducer = (state, { type, payload}) => {
// 其他逻辑
}
export default composeReducer(reducer, list('users/FETCH_SUCCESS')) list 只是一个例子,实际上在项目中是有不少 reducer 会有相同逻辑的。 |
@yesmeck 👍 ,之前一直低估了 reducer enhancer 的作用。 |
@sorrycc 能说说为什么吗?用 |
我也建议可以一次传入多个model的方法,大型项目可能会有很多model,我现在都是全部require(import)进来,然后一个一个model,其实不太方便,我现在的写法是:
|
这很 D.VA。 |
发现user-dashboard中有antd form组件的使用,我记得是不能用于pure component的,现在可以了吗? |
@codering 我没记得有限制, antd 的问题可以到 https://github.com/ant-design/ant-design/issues 提问。 |
你好,我想用您的这个dva,目前用 React Webpack Redux 脚手架生成的目录结构,参照您example中user-dashboard例子改了代码,可是start之后没有任何内容,您是否可以帮我看看究竟哪里出了问题,我的项目地址:https://github.com/baiyulong/lenovo_parts |
@baiyulong 为啥不直接基于 user-dashboard 的目录结构做呢? |
@sorrycc 我现在就用user-dashboard的目录结构,请问dva的路由是有特殊处理或者写法么? |
@baiyulong dva的路由并无特殊写法,你的问题请尝试:
|
@nikogu 非常感谢,我把嵌套的拿出来以后就好了 |
你好,请问dva能不能支持model的热加载? |
@kkkf1190 正在考虑这一块,会支持的。 |
👍 |
Is there a chance we can get English translation of the docs? |
业务代码中,常见这样的例子,某一局部状态更新,牵一发而动全身,很多地方不需要重新渲染的,也重新渲染,大大降低页面性能。可否添加这个功能,自动分析redux connect依赖的state,减少不必要的mapStateToProps计算和re-render 👍 |
very good |
unofficial translation Why Dva?Redux is good. But there are too many concepts, separated reducers, sagas and actions (split into different files)
What's Dva?It's a lite wrapper over existing framework (redux + react-router + redux-saga ...). No new concept involved. < 100 lines code. ( Inspired by elm and choo. ) It's a framework, not a library. Like Ember.js, it constrains the way you write each part. It's more controllable for teamwork. Dva encapsulates all dependencies except react and react-dom as peerDependencies Its implementation introduces new syntaxes as less as possible. It reuses the dependencies. For exp., router definition is exactly the same way as react-router's JSX. The core functionality is app.model({
namespace: 'products',
state: {
list: [],
loading: false,
},
subscriptions: [
function(dispatch) {
dispatch({type: 'products/query'});
},
],
effects: {
['products/query']: function*() {
yield call(delay(800));
yield put({
type: 'products/query/success',
payload: ['ant-tool', 'roof'],
});
},
},
reducers: {
['products/query'](state) {
return { ...state, loading: true, };
},
['products/query/success'](state, { payload }) {
return { ...state, loading: false, list: payload };
},
},
}); We used to create key point:
How to UseSee examples Roadmap
FAQ
Compatible with redux-devtool, css livereload. Need more work for hot-reload
sure
yes
No IE8 due to redux-saga. (Later may apply thunk, promise, observable as extensions on the effects layer) |
请问类似 ['products/query']: function*() {}
['products/query'](state) {} 是什么语法?数组能用作函数名吗? |
@clemTheDasher Function name can be computed key(NOT array) in JavaScript. More detail reference to Method definitions | MDN :) var obj = {
property( parameters… ) {},
*generator( parameters… ) {},
async property( parameters… ) {},
async* generator( parameters… ) {},
// with computed keys:
[property]( parameters… ) {},
*[generator]( parameters… ) {},
async [property]( parameters… ) {},
// compare getter/setter syntax:
get property() {},
set property(value) {}
}; |
新人报道,到此一游,继续努力学习前端知识 |
@clemTheDasher That's computed property. |
为什么 count https://github.com/dvajs/dva/tree/master/examples/count 这个链接404了呢 |
学习! |
向大神看齐 |
感谢大神,感谢开源 |
am I not allowed to learn from you guys! |
学习了,谢谢有这么方便的框架供我们使用 |
github的demo链接都已经失效了。 |
@sorrycc 现在dva支持服务端渲染吗 |
Redux流派的写法,简洁,修改状态只需要一行,但是似乎把几行代码通过语法糖写到一起了。但我还是需要用 从某些角度上来讲,Vuex的思路更容易读,也更自然。类似这样写(不完全是哦)。 const mutation = {
['products/query'](state) {
state.loading = true
},
['products/query/success'](state, payload) {
state.loading = false
state.list = payload
}
} 从代码上看,我只关心我(同步)修改哪些状态。Vuex在外面应该还包了一层做了状态下一站投递。可能在投递之前还会做一些防御性检查(猜测),或者植入钩子。 |
问下我已经dva的官网的例子 页面出不来报错了 是升级了吗 |
ES6 允许字面量定义对象时,(表达式)作为对象的属性名,即把表达式放在方括号内。
|
有个疑问啊,'products/query'这种方式去处理reducers的调用,而且与namespace通过字符串的方式关联,后期如果项目变大,比如上百个方法。如果我的namspace必须要改。要改一百方法了? |
这里不知道是否有支持? |
Why dva ?
经过一段时间的自学或培训,大家应该都能理解 redux 的概念,并认可这种数据流的控制可以让应用更可控,以及让逻辑更清晰。
但随之而来通常会有这样的疑问:概念太多,并且 reducer, saga, action 都是分离的(分文件)。
这带来的问题是:
还有一些其他的:
而 dva 正是用于解决这些问题。
What's dva ?
dva 是基于现有应用架构 (redux + react-router + redux-saga 等)的一层轻量封装,没有引入任何新概念,全部代码不到 100 行。( Inspired by elm and choo. )
dva 是 framework,不是 library,类似 emberjs,会很明确地告诉你每个部件应该怎么写,这对于团队而言,会更可控。另外,除了 react 和 react-dom 是 peerDependencies 以外,dva 封装了所有其他依赖。
dva 实现上尽量不创建新语法,而是用依赖库本身的语法,比如 router 的定义还是用 react-router 的 JSX 语法的方式(dynamic config 是性能的考虑层面,之后会支持)。
他最核心的是提供了
app.model
方法,用于把 reducer, initialState, action, saga 封装到一起,比如:在有 dva 之前,我们通常会创建
sagas/products.js
,reducers/products.js
和actions/products.js
,然后在这些文件之间来回切换。介绍下这些 model 的 key :(假设你已经熟悉了 redux, redux-saga 这一套应用架构)
How to use
参考 examples:
Roadmap
devtool
热替换支持Effects 考虑通过扩展的方式接入 thunk, promise, observable 等方案,基本目的是可以兼容 IE8Component 之间还要传递 dispatch 太麻烦了,考虑下方案FAQ
除了热替换还待适配,其他的比如 redux-devtool, css livereload 等都是兼容的。
可以。
是的。
IE8 不支持,因为使用了 redux-saga 。(后面会考虑以扩展的方式在 effects 层支持 thunk, promise, observable 等)
The text was updated successfully, but these errors were encountered: