sorrycc / blog

💡

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

dva 2.0 发布

sorrycc opened this issue · 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

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"
  }
}]

(完)

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

点赞

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

为什么有这个修改呢?

准备跟进..

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

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

前排

commented

mark,晚上学习跟进

dispatch(effectAction) => Proimse
👍👍👍

commented

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

准备升级看看

commented

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

commented

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

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

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

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

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

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

dispatch(effectAction) => Proimse

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

有没有dva 2.0完成的demo

d.ts有吗?

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

养肥了再用 嘿嘿

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

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

一直没有结合 immutable 的方案呢

commented

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

onError这个钩子没作用了

commented

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

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

养肥了把 你们先把坑填好

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

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

怎么将 hashHistory 改成 browserHistory 啊?

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

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

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

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

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

commented

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

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

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

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

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

@sorrycc 请问一下,我照着
image

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

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

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

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

commented

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

commented

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

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

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

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

needs english translation please :)

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

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

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

commented

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

commented

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

@yangbin1994

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

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

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

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

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

commented

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

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

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

好实用.赶紧试用一下.

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

error1

error2

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

image

是不是可以忽略它

dva-vue dva-core 整合的 vue

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

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

大家好~

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

commented

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

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

commented

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

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

commented

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

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

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

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

commented

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

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 } });

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 } });

可以的

而且可以省略括号