Skip to content
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 2.0 发布 #48

Open
sorrycc opened this issue Sep 4, 2017 · 79 comments
Open

dva 2.0 发布 #48

sorrycc opened this issue Sep 4, 2017 · 79 comments
Labels

Comments

@sorrycc
Copy link
Owner

sorrycc commented Sep 4, 2017

距离 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

dva@1.0 用户如何升级?

原则上推荐升级到基于 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 sorrycc added the DvaJS label Sep 4, 2017
@cuitianze
Copy link

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

@Wuuuu
Copy link

Wuuuu commented Sep 4, 2017

点赞

@kenan2002
Copy link

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

为什么有这个修改呢?

@RaoHai
Copy link

RaoHai commented Sep 4, 2017

准备跟进..

@sorrycc
Copy link
Owner Author

sorrycc commented Sep 4, 2017

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

@terminalqo
Copy link

terminalqo commented Sep 4, 2017

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

@Hello-Tan
Copy link

前排

@xiashuyuan
Copy link

mark,晚上学习跟进

@xiaosongxiaosong
Copy link

dispatch(effectAction) => Proimse
👍👍👍

@yangbin1994
Copy link

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

@luokailuo
Copy link

准备升级看看

@duwei54
Copy link

duwei54 commented Sep 7, 2017

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

@bubkoo
Copy link

bubkoo commented Sep 7, 2017

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

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

@WangYang-Rex
Copy link

WangYang-Rex commented Sep 7, 2017

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

@daCapricorn
Copy link

dva-boilerplate-electron 是否会更新dva@2.0?

@luofish
Copy link

luofish commented Sep 11, 2017

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

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

dispatch(effectAction) => Proimse

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

@zkeyword
Copy link

有没有dva 2.0完成的demo

@varHarrie
Copy link

d.ts有吗?

@hopperhuang
Copy link

hopperhuang commented Sep 13, 2017

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

@jomalonejia
Copy link

养肥了再用 嘿嘿

@lanxxg
Copy link

lanxxg commented Sep 14, 2017

用dva-cli@0.8.1 dva new 新建的项目是基于dva@2.0 ,如果想用dva-react-router-3@1.0如何设置?

@xiebl
Copy link

xiebl commented Sep 14, 2017

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

@pengfeiWang
Copy link

一直没有结合 immutable 的方案呢

@waynerQiu
Copy link

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

@Gavinchen92
Copy link

onError这个钩子没作用了

@zhaoyao91
Copy link

zhaoyao91 commented Jan 29, 2018

同名 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设计上的灾难。

@devmsg
Copy link

devmsg commented Feb 2, 2018

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

@yangbin1994
Copy link

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

@zhaoyao91
Copy link

@yangbin1994

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

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

@birdycn
Copy link

birdycn commented Feb 24, 2018

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

@tuibian
Copy link

tuibian commented Mar 17, 2018

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

@angelporo
Copy link

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

@qhxin
Copy link

qhxin commented Apr 3, 2018

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

@shenqihui
Copy link

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

@472756921
Copy link

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

@billychou
Copy link

好实用.赶紧试用一下.

@comll18
Copy link

comll18 commented May 11, 2018

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

error1

error2

@SynChron1zed
Copy link

SynChron1zed commented Jun 11, 2018

@sorrycc 现在有一个问题请教下
dva@2.0+后是需要react@16.0+ 但是dva-cli 后 react-router-redux@5.0.0-alpha.6 确要react@15.0

image

是不是可以忽略它

@BleemIs42
Copy link

dva-vue dva-core 整合的 vue

@13296634573
Copy link

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

@cheng-xiaofeng
Copy link

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

@programmer-RN
Copy link

大家好~

// 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", 恳切大家可以回复协助,谢谢

@pengshaosu
Copy link

pengshaosu commented Oct 18, 2018

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

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

@nelhu
Copy link

nelhu commented Nov 26, 2018

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

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

@nelhu
Copy link

nelhu commented Nov 27, 2018

同名 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只是提供了快捷,并没有改变之前使用场景的数据流
    可以这么理解吗?

@WavinFlag
Copy link

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

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

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

@pilot-study-test
Copy link

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

@lhw0304
Copy link

lhw0304 commented Jan 1, 2020

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
Copy link

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
Copy link

而且可以省略括号

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests