blog icon indicating copy to clipboard operation
blog copied to clipboard

dva 2.0 发布

Open sorrycc opened this issue 8 years ago • 79 comments

距离 dva@1 发布已经快整整一年,经过一段时间断断续续的开发,dva@2 终于能和大家见面了。

2.0 最主要的变化是提取了 dva-core,是仅封装了 redux 和 redux-saga 的纯数据流方案。这使得 dva 可以应用在除 react 之外的其他领域,比如 RN、小程序、游戏、vue 等领域;同时也可满足同一领域的多种实现,比如为 react 应用不同的路由方案的 dva-react-router-3dva-no-router。(#530)

本次发布包含 dva-core 和 3 个 react 实现:

此外,还有一些社区基于 dva-core 的实现:

改进

dispatch(effectAction) => Proimse

为了方便在视图层 dispatch action 并处理回调,比如 #175,我们在 dispatch 里针对 effect 类型的 action 做了返回 Promise 的特殊处理。

例如:

dispatch({ type: 'count/addAsync' })
  .then(() => {
    console.log('done');
  });

新增 dva/dynamic 接口,配合 react-router@4 处理组件的按需加载

react-router@4 的路由是组件式的,手动处理组件的按需加载并结合 model 和 app 有点麻烦,所有封装了 dva/dynamic util 方法。

const Users = dynamic({
  app,
  models: () => [
    import('./models/users'),
  ],
  component: () => import('./routes/Users'),
});

// render
<Route exact path="/users" component={Users} />

take 自动补全 namespace 前缀

注:之前手动加 namespace 的会收到一个 warning。

{
  namespace: 'count',
  effects: {
    *a(action, { take }) {
      // Before
      yield take('count/b');

      // After
      yield take('b');
    }
  }
}

effect 前后会额外触发 /@@start/@@end 的 action,可利用此约定实现 put 的同步执行

例如:

yield put({ type: 'addDelay', payload: { amount: 2 } });
yield take('addDelay/@@end');
const count = yield select(state => state.count);
yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

参考用例 dva/effects-test.js at d49e3567eaadf06d12c701e670b2ba3bbe043553 · dvajs/dva · GitHub

Break Changes

react-router@4

路由基于 react-router@4 实现,写法上会有不同。

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

// model.js
export default {
  namespace: 'count',
  reducers: {
    a() {},
  },
  effects: {
    *a() {},
  }
}

// 只会执行 effects.a 不会执行 reducers.a
dispatch({ type: 'count/a' });

删除 dva/mobile

之前的 dva/mobile 其实是无路由版的 dva,所以可以用 dva-no-router 代替。

history 的 location 属性上不再包含 query

这是 history 库的变动,有和 query 相关的请用 query-string 处理一遍。

FAQ

[email protected] 用户如何升级?

原则上推荐升级到基于 react-router@4 的 dva@2,react-router@4 路由的去中心化带来的好处绝对值得一学,比如布局嵌套、Inclusive 路由、路由抽象等等。可以参考 user-dashboard 升级到 dva@2 的 commit

但肯定会有出于成本考虑,既想用 dva@2,又想继续用老版本的路由方案的,我们为大家准备了 dva-react-router-3。大家可以参考 dva-example-react-router-3 进行升级。而为了减少代码修改量,比如把所有的 import xx from 'dva' 改成 import xx from 'dva-react-router-3',大家可以通过 babel-plugin-module-resolver 进行构建时替换:

["module-resolver", {
  "alias": {
    "dva": "dva-react-router-3"
  }
}]

(完)

sorrycc avatar Sep 04 '17 06:09 sorrycc

前排占楼,跟不上前端时代潮流了

cuitianze avatar Sep 04 '17 07:09 cuitianze

点赞

Wuuuu avatar Sep 04 '17 07:09 Wuuuu

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

为什么有这个修改呢?

kenan2002 avatar Sep 04 '17 07:09 kenan2002

准备跟进..

RaoHai avatar Sep 04 '17 07:09 RaoHai

@kenan2002 因为加了 dispatch(effectAction) => Promise 的功能,action 到 effect 这一层就返回了,到不了 reducer 。

sorrycc avatar Sep 04 '17 07:09 sorrycc

重学react-router@4 是个大项目...

terminalqo avatar Sep 04 '17 07:09 terminalqo

前排

Hello-Tan avatar Sep 04 '17 07:09 Hello-Tan

mark,晚上学习跟进

xiashuyuan avatar Sep 04 '17 07:09 xiashuyuan

dispatch(effectAction) => Proimse 👍👍👍

xiaosongxiaosong avatar Sep 04 '17 08:09 xiaosongxiaosong

看到小程序可以用dva-core,我就放心了

yangbin1994 avatar Sep 04 '17 08:09 yangbin1994

准备升级看看

hupeople avatar Sep 04 '17 09:09 hupeople

@sorrycc 大神,子组件中用dynamic 怎么注入app呢

duwei54 avatar Sep 07 '17 02:09 duwei54

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

感觉这个改动有点大,修改了原生 redux 的行为,容易采坑

bubkoo avatar Sep 07 '17 04:09 bubkoo

赞,准备开始学dva,紧跟前端潮流,哈哈哈

WangYang-Rex avatar Sep 07 '17 06:09 WangYang-Rex

dva-boilerplate-electron 是否会更新[email protected]

daCapricorn avatar Sep 08 '17 06:09 daCapricorn

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

感觉这个改动太大了,之前很多代码基于此的,很方便的在effect执行之前先修改state

dispatch(effectAction) => Proimse

这个改动好像使得dva的使用方式可以多元化了,比如可以 把数据放在react的state里面了,dispatch effect -> promise -> update state. 而不是像以前必须要通过reducer了,这个改动好或者坏?

luofish avatar Sep 11 '17 03:09 luofish

有没有dva 2.0完成的demo

zkeyword avatar Sep 12 '17 08:09 zkeyword

d.ts有吗?

varHarrie avatar Sep 12 '17 09:09 varHarrie

写得太精彩了。6666666。由衷佩服那个添加一个promiseMiddlerware,并把对应的reslove和reject生成一个map,用于给saga调用的方案。居然还有这操作。。。。。

hopperhuang avatar Sep 13 '17 07:09 hopperhuang

养肥了再用 嘿嘿

jomalonejia avatar Sep 14 '17 00:09 jomalonejia

[email protected] dva new 新建的项目是基于[email protected] ,如果想用[email protected]如何设置?

lanxxg avatar Sep 14 '17 08:09 lanxxg

升级到2.0之后 全局的onError不起作用了?

xiebl avatar Sep 14 '17 11:09 xiebl

一直没有结合 immutable 的方案呢

pengfeiWang avatar Sep 15 '17 01:09 pengfeiWang

@sorrycc 同学, 有木有考虑出一个Rax+dva-core的demo啊? dva-core 没有使用说明很郁闷!

waynerQiu avatar Sep 17 '17 05:09 waynerQiu

onError这个钩子没作用了

Gavinchen92 avatar Sep 18 '17 01:09 Gavinchen92

@Gavinchen92 Route现在是组件了,钩子函数的操作可以在容器组件的生命周期里去做 参考

programmer-yang avatar Sep 18 '17 01:09 programmer-yang

各个子项目的文档有了吗,我翻了一下 README.md 都是空的

hbrls avatar Sep 19 '17 01:09 hbrls

养肥了把 你们先把坑填好

SynChron1zed avatar Sep 19 '17 08:09 SynChron1zed

dispatch(effectAction) => Proimse 这个太实用了

BurnhamZhang avatar Sep 21 '17 08:09 BurnhamZhang

dva 可以接小程序,点赞!!

suuuuuuuuperman avatar Sep 28 '17 02:09 suuuuuuuuperman

怎么将 hashHistory 改成 browserHistory 啊?

xiaohaiH avatar Sep 28 '17 04:09 xiaohaiH

请问,怎么根据用户是否登录来进行路由的跳转啊???

xiaohaiH avatar Oct 03 '17 11:10 xiaohaiH

william-xue avatar Oct 20 '17 09:10 william-xue

我瞎几把写的,欢迎吐槽 demo

yyjazsf avatar Oct 22 '17 15:10 yyjazsf

dva2.0 没有atool-build的demo吗,急需

zfhslfgit avatar Oct 23 '17 07:10 zfhslfgit

@sorrycc 最后FAQ一段里,user-dashboard 升级到 dva@2 的 commit 这句的链接指向的是旧的版本,代码已经不对了,希望可以改一下,避免其他人再按照错误示例迁移。

daskyrk avatar Oct 25 '17 06:10 daskyrk

我是用pathname==“/”监听初始页面,在mapStateToProps获取初始数据出现异步 const { issues, numbers: numberor } = state.bet; console.log(issues);此处在state.bet未获取完成数据之前执行,怎么回事

zaosw2008 avatar Oct 25 '17 06:10 zaosw2008

image 今天用着用着突然报这个错,请问什么原因? 目前用的是版本1

Dzhaolei avatar Oct 30 '17 10:10 Dzhaolei

你好,打扰你一下,请问一下我如果想将项目中的图片放在cdn上去,在roadhogrc里面怎么配置?配置publicPath的话全部都会变成cdn路径 @sorrycc

wuyanghou avatar Oct 31 '17 09:10 wuyanghou

用的前一个版本做的项目,如果不升级的话会不会有影响?

ChengWenxing avatar Nov 09 '17 05:11 ChengWenxing

@sorrycc 用的前一个版本做的项目,如果不升级的话会不会有影响?

ChengWenxing avatar Nov 14 '17 09:11 ChengWenxing

ant-design-pro 切换为browserHistory 刷以后白屏

lofzefjg avatar Nov 19 '17 12:11 lofzefjg

@sorrycc 请问一下,我照着 image

这个做的,但是报错,错误如下 image 请问一下,这个是怎么回事啊

zoushenglin avatar Nov 25 '17 13:11 zoushenglin

@daskyrk 请问一下,dva@1升级到dva@2怎么配置啊,上面的教程不行,配置了之后报错,求帮忙解决啊

zoushenglin avatar Nov 27 '17 10:11 zoushenglin

Dispatch =>promise 实在好,明天准备试一试

Irislm avatar Dec 18 '17 16:12 Irislm

@sorrycc 请问下哪里可以看到完整的API呢?例如antd pro中 dynamic.setDefaultLoadingComponent 这个API

FrendEr avatar Dec 20 '17 10:12 FrendEr

Reactjs 中的 Dva 这么一封装,有点vuejs的感觉了,Models 对应 vue 组件的Script,整合了页面响应和Store;模板是独立组件,对应vuejs的Templet。Dvajs的好处是用vue的方式来使用React,可以使用React的丰富的生态资源。vuejs更容易上手和理解,所有概念都整合在一起,不用管细节就能用,弱项是生态

anuxs avatar Dec 22 '17 03:12 anuxs

@anuxs ...

afc163 avatar Dec 22 '17 03:12 afc163

我用dva-cli 创建项目后 不安装不了其他库了,是什么原因

ooolog avatar Dec 25 '17 13:12 ooolog

有点MST的意思,但定位为framework就限制了很多可能并提高了使用门槛。

webyom avatar Dec 27 '17 10:12 webyom

请问一下,这个生成的项目的模板是index.ejs,可以改成index.html吗,我在index.ejs里引用的css都不生效不知道怎么回事。

dsmelon avatar Jan 09 '18 11:01 dsmelon

蹲坑观摩,还在使用@dva1.X

xudihui avatar Jan 10 '18 09:01 xudihui

needs english translation please :)

locosoft1986 avatar Jan 18 '18 04:01 locosoft1986

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

@sorrycc 在 PromiseMiddleware 判断 isEffect 的逻辑里 增加一个 判断是否是 reducers 的方法 isReducer ,如果是 reducers 则 同时调用一下 next(action) 确保 reducer 也可以对该 action 进行处理。不知这么处理是否可行 ?

yvanwangl avatar Jan 24 '18 09:01 yvanwangl

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

这个改动感觉是设计被实现牵着鼻子走了。这个breaking change的解释竟然是因为另一处升级而导致的副作用?实在是匪夷所思。且不论原因,这个设计上的变化也是不合理的。

所谓effects,可以理解为side effects,其为action的伴随效果,或副作用,表现为对action(reducer)进行纯扩展(不改动原有逻辑,而增加扩展逻辑,支线逻辑,旁路逻辑,或曰,副逻辑),这自然而然。而这个breaking change改变了这个设定,让effects实际上变成了async action,实在不妥,不仅破坏了api的兼容性,而且逻辑和命名也反而变得矛盾了。

其实async action并非不好,但这次升级完全可以通过增加async action的方式来实现,而非改变一个定义准确的概念还破坏了兼容性。我觉得这个breaking change是dva2设计上的灾难。

zhaoyao91 avatar Jan 29 '18 09:01 zhaoyao91

@sorrycc 在使用 [email protected] 结合 nextjs 做ssr的时候 在注册 model的时候还是会有#553 的问题 难道也要跟这个解决方案一样么?

devmsg avatar Feb 02 '18 03:02 devmsg

@zhaoyao91 派发 action,同时触发同名 reducer 和 effect 的使用场景是什么?

yangbin1994 avatar Feb 03 '18 06:02 yangbin1994

@yangbin1994

例如做一个log或者发一个数据统计。或者,状态是改成requesting-data,而side effect是实际执行拉取动作,完成后更新状态为data-fetched或failed。

用例是一方面,关键是一个功能的效果应该是和其概念定义保持。如果觉得没有这个用例,那大可不要这个feature,而做一个async action的feature,而不是因为图方便而混淆概念。

zhaoyao91 avatar Feb 03 '18 06:02 zhaoyao91

请问一下,dva2.X的onerror钩子没有了?

birdycn avatar Feb 24 '18 17:02 birdycn

@sorrycc 请问2.x的dynamic函数是怎么把Rote的path设置成对应的地址

tuibian avatar Mar 17 '18 17:03 tuibian

需要好好学习下dva了 , 光是用redux确实写的相同的东西太多.

angelporo avatar Mar 19 '18 10:03 angelporo

dva-react-router-3 无法通过编译,好像是需要调用react-router-3但是实际使用了react-router-4,怎么回事呢。。

qhxin avatar Apr 03 '18 05:04 qhxin

时隔几个月,才发现新版本发布了。

shenqihui avatar Apr 07 '18 14:04 shenqihui

请问.umirc.mock怎么用。。。。

472756921 avatar Apr 15 '18 10:04 472756921

好实用.赶紧试用一下.

billychou avatar May 07 '18 08:05 billychou

@sorrycc 云谦大神,dva2项目打包后,在ie11下面加载路由时报错,导致项目运行不了,这是什么原因呢?没打包运行是正常的 error3

error1

error2

comll18 avatar May 11 '18 09:05 comll18

@sorrycc 现在有一个问题请教下 [email protected]+后是需要[email protected]+ 但是dva-cli 后 [email protected] 确要[email protected]

image

是不是可以忽略它

SynChron1zed avatar Jun 11 '18 02:06 SynChron1zed

dva-vue dva-core 整合的 vue

ISeekTruth avatar Jun 19 '18 10:06 ISeekTruth

@sorrycc 你好,能否把 dva-example-react-router-3 再发一下,现在已经打不来,打算升级dva而不升级路由

13296634573 avatar Jul 13 '18 03:07 13296634573

app.model(require('./models/users').default);有default和没有default有什么区别?default是后来加的吗?因为我现在做的项目中没有default也能运行,而根据文档写的demo却会报错.

cheng-xiaofeng avatar Sep 05 '18 09:09 cheng-xiaofeng

大家好~

// 1. Initialize
const app = dva({
  onReducer: (reducer) => {
    if (createPersistorIfNecessary(app._store)) {
      const newReducer = persistReducer(persistConfig, reducer)
      setTimeout(() => $persistor && $persistor.persist(), 0)
      return newReducer
    } else {
      return reducer
    }
  },
  history: createHistory(),
  onError,
 })

createPersistorIfNecessary(app._store)的app_store 是 null, 而且一直出现“redux-persist failed to create sync storage, falling back to memory storage", 恳切大家可以回复协助,谢谢

programmer-RN avatar Sep 06 '18 09:09 programmer-RN

dispatch(effectAction) => Proimse 为了方便在视图层 dispatch action 并处理回调,比如 #175,我们在 dispatch 里针对 effect 类型的 action 做了返回 Promise 的特殊处理。

这个把reducers中的方法封装一下放到effect里,这样间接的reducers也可以进行Promise回调的操作。

pengshaosu avatar Oct 18 '18 11:10 pengshaosu

@kenan2002 因为加了 dispatch(effectAction) => Promise 的功能,action 到 effect 这一层就返回了,到不了 reducer 。

那如果在这个effect里发出了另一个触发reducer的action,这种情况呢, 会到reducer吗

nelhu avatar Nov 26 '18 09:11 nelhu

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

感觉这个改动太大了,之前很多代码基于此的,很方便的在effect执行之前先修改state

dispatch(effectAction) => Proimse

这个改动好像使得dva的使用方式可以多元化了,比如可以 把数据放在react的state里面了,dispatch effect -> promise -> update state. 而不是像以前必须要通过reducer了,这个改动好或者坏?

确实扩展了action的使用。现在可以把dispatch action的使用分为两个场景:

  1. 当需要在视图内使用dispatch action并根据回调改变视图的state时, 使用 dispatch(effectAction) - promise - update component state。 此时不允许有同名的reducer, 因为action到effect这一层就返回了。
  2. 经典的使用场景: dispath(action) - reducer - effect - state。 那么> > dispatch(effectAction) => Proimse只是提供了快捷,并没有改变之前使用场景的数据流 可以这么理解吗?

nelhu avatar Nov 27 '18 03:11 nelhu

同名 reducer 和 effect 不会 fallthrough(即两者都执行),而是仅执行 effect

看了下源代码,在 PR https://github.com/dvajs/dva/pull/1602 之后这个行为已经改变了,现在能够正常地 fall through。 这个修改包含在 2.2.0 开始的版本中。 @nelhu @zhaoyao91

@sorrycc 如果设计目的上并没有特意禁止同名 reducer 和 effect 的话,这个 bug 算是 fix 了;建议更新一下文章。

WavinFlag avatar Jan 31 '19 02:01 WavinFlag

我升dva2后,路由切换会触发double次监听,且都是PUSH的,搞得很无奈。

pilot-study-test avatar Mar 25 '19 01:03 pilot-study-test

yield put({ type: 'addDelay', payload: { amount: 2 } }); yield take('addDelay/@@end'); const count = yield select(state => state.count); yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } }); ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 可不可以这样写呢 yield (yield put({ type: 'addDelay', payload: { amount: 2 } });) const count = yield select(state => state.count); yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

lhw0304 avatar Jan 01 '20 08:01 lhw0304

yield put({ type: 'addDelay', payload: { amount: 2 } }); yield take('addDelay/@@EnD'); const count = yield select(state => state.count); yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } }); ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 可不可以这样写呢 yield (yield put({ type: 'addDelay', payload: { amount: 2 } });) const count = yield select(state => state.count); yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } });

可以的

miaozilong avatar Apr 07 '20 17:04 miaozilong

而且可以省略括号

miaozilong avatar Apr 07 '20 17:04 miaozilong