Dva: [讨论] - 关于页面初始数据依赖的声明问题

创建于 2017-12-17  ·  3评论  ·  资料来源: dvajs/dva

官方文档 和 hackernews示例中,都使用了在model的subscription中监听匹配history url的方式为页面加载初始数据,如下。

//摘自api文档
app.model({
  namespace: 'todo',
  // ... 
  subscriptions: {
    setup({ history, dispatch }) {
      // Subscribe history(url) change, trigger `load` action if pathname is `/`
      return history.listen(({ pathname }) => {
        if (pathname === '/') {
          dispatch({ type: 'load' });
        }
      });
    },
  },
});

传送门:类似写法的 dva-hackernews的item model

这与通常见到的在页面组件的生命周期加载数据有所不同,比如同样是hakernews的例子,我们可以选择在ListPage 的componentWillMount或componentDidMount去dispatch 相应的effects action做请求,甚至从server render的角度思考,可以添加额外的生命周期(比如next.js的getInitProps)来负责声明这种页面的初始数据依赖。

目前把页面的初始数据依赖放到model的subcription中的方式,个人存在以下疑问:

  1. url match逻辑重复: 解析url参数并转发到业务逻辑是router的职责,从hackernews的例子能看出来 已经 有一部分重复了,甚至会用到pathToRegex这样相对“底层”的库(react-router/express背后也是用的它做url匹配和解析)
  2. 职责分离:不同的做法对应不同的语义,是由页面声明该页依赖哪些数据,还是由model声明在什么url下执行数据加载?
  3. 页面失去了对请求的控制权,如果某个页面想在请求成功或失败后执行特定的逻辑,会比较难实现 ,因为页面本身对加载数据这个动作是没有感知的
  4. 如何应对server render/isomorphic场景,其实是3的延续,在server render下,需要“先加载页面依赖的数据,再执行页面渲染”,而如果对请求的声明根本不在页面级,要做到这事就比较麻烦了
  5. subscription的设计似乎是受elm的影响,但是在elm中subscription的使用其实也并不多,只是用来对付websocket等场景,初始请求还是通过页面声明init做的。

当然,dva并没有限制采用哪种方式,在dva中使用页面组件生命周期的做法是完全可行的,只是我觉得具有示范作用的官方文档和示例都用了另一种做法,很可能还有我不知道的考量,之前也加了微信群提问,但没能得到答案(有朋友说是因为dva希望页面组件也是functional component,确实是一个点,但似乎没有那么强的说服力),因此开issue叨扰,见谅。
@sorrycc

discussion wontfix

所有3条评论

model 的inithook

              邮箱:[email protected]

签名由 网易邮箱大师 定制
在2017年12月17日 16:30,Qin Junwen 写道: 在官方文档 和 hackernews示例中,都使用了在model的subscription中监听匹配history url的方式为页面加载初始数据,如下。
//摘自api文档
app.model({
namespace: 'todo',
// ...
subscriptions: {
setup({ history, dispatch }) {
// Subscribe history(url) change, trigger load action if pathname is /
return history.listen(({ pathname }) => {
if (pathname === '/') {
dispatch({ type: 'load' });
}
});
},
},
});
传送门:类似写法的 dva-hackernews的item model
这与通常见到的在页面组件的生命周期加载数据有所不同,比如同样是hakernews的例子,我们可以选择在ListPage 的componentWillMount或componentDidMount去dispatch 相应的effects action做请求,甚至从server render的角度思考,可以添加额外的生命周期(比如next.js的getInitProps)来负责声明这种页面的初始数据依赖。
目前把页面的初始数据依赖放到model的subcription中的方式,个人存在以下疑问:

url match逻辑重复: 解析url参数并转发到业务逻辑是router的职责,从hackernews的例子能看出来 已经 有一部分重复了,甚至会用到pathToRegex这样相对“底层”的库(react-router/express背后也是用的它做url匹配和解析)
职责分离:不同的做法对应不同的语义,是由页面声明该页依赖哪些数据,还是由model声明在什么url下执行数据加载?
页面失去了对请求的控制权,如果某个页面想在请求成功或失败后执行特定的逻辑,会比较难实现 ,因为页面本身对加载数据这个动作是没有感知的
如何应对server render/isomorphic场景,其实是3的延续,在server render下,需要“先加载页面依赖的数据,再执行页面渲染”,而如果对请求的声明根本不在页面级,要做到这事就比较麻烦了
subscription的设计似乎是受elm的影响,但是在elm中subscription的使用其实也并不多,只是用来对付websocket等场景,初始请求还是通过页面声明init做的。

当然,dva并没有限制采用哪种方式,在dva中使用页面组件生命周期的做法是完全可行的,只是我觉得具有示范作用的官方文档和示例都用了另一种做法,很可能还有我不知道的考量,之前也加了微信群提问,但没能得到答案(有朋友说是因为dva希望页面组件也是functional component,确实是一个点,但似乎没有那么强的说服力),因此开issue叨扰,见谅。
@sorrycc

—You are receiving this because you are subscribed to this thread.Reply to this email directly, view it on GitHub, or mute the thread.

{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/dvajs/dva","title":"dvajs/dva","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/dvajs/dva"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"[讨论] - 关于页面数据依赖的问题 (#1402)"}],"action":{"name":"View Issue","url":"https://github.com/dvajs/dva/issues/1402"}}}

@yangbin1994

model的inithook指的是?
我在model文档里没看到呢。

假设有这个Hook,其实和在subscription中做似乎也没有本质上的不同,上述1-4点疑问仍然存在

此问题已自动标记为陈旧,因为它最近没有活动。 如果没有进一步的活动发生,它将被关闭。 感谢你的贡献。

此页面是否有帮助?
0 / 5 - 0 等级