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

feat: v2.0 #90

Merged
merged 12 commits into from
May 24, 2022
Merged

feat: v2.0 #90

merged 12 commits into from
May 24, 2022

Conversation

awmleer
Copy link
Member

@awmleer awmleer commented May 19, 2022

先前曾发过一个 RFC #37,也收到了很多社区朋友的反馈,不过由于年代有点久远了,这里把一些信息重新整理一下。

背景 & 动机

在 hox v1 中,我们的实现方案是在应用的 React 组件树之外,额外创建一个组件树,以存储 hox 中的 model。然而,这种方案渐渐显露出较多的弊端:

  1. 对渲染环境的要求比较苛刻,强依赖 react-dom,SSR、RN、小程序都无法使用(rn  #10 nextjs 中使用不了 #11 微信小程序框架Remax中无法使用 #13)。即便可以通过 custom renderer 解决,但是又会导致包体积较大(v1.1.0 引入 react-reconciler 后的体积徒增问题 #26),甚至还会出现一些比较玄学的问题(使用生产环境cdn react.production.min.js,会导致死循环 #88 修改代码热更新后组件状态不更新 #56 一直加载中是怎么回事? #78)。
  2. 无法和 Context 配合使用,在某些场景下瓶颈非常明显(与上下文 Context 以及 useContext 的配合问题 #20 与umi 的 useRequest 一起使用时,捕获不到全局错误 #36
  3. 生命周期不够完善,无法控制何时装载何时卸载(是否需要提供一个 unmount 的 API,在微前端场景,需要卸载数据 #12 建议增加一个销毁方法 #73 createModel 后的每个状态都是全局单例,组件销毁后也不释放么 #50 有没有一个api可以重置数据到初始化状态? #70
  4. 强制将数据存储到全局,无法支持局部状态

2.0 整体思路

如果要解决上面提到的这些问题,可以发现有一些方向是非常明确的:

  1. 底层要走 Context 通信
  2. 不应该基于 react-reconciler 自己包装一个 Custom Renderer,难以维护,而且对于包体积不友好

下面来分别针对这两点展开介绍一下思路:

Context

如果完全基于 Context,那么大致思路就是 reto 了,所以当时 RFC 的评论区中很多朋友也在问:

  • 和其他基于 Context 的状态管理库(比如 unstated-next)有什么区别?只是性能更好、支持 memo 么?
  • createModel 这种直接创建全局状态的语法还是很好用的,如果全都是 Provider,在一些简单场景下会非常痛苦,为什么一定要废弃全局状态?

所以在 2.0 的实现中,同时支持了创建全局状态 createGlobalStore 和创建局部状态 createStore,而且 createGlobalStore 的用法、能力几乎和 v1 的 createModel 是一模一样的。

复用环境中已有的 React Renderer

如果不用 react-reconciler 自己封装一个 Custom Renderer,那就要复用业务中已有的 React Renderer,例如 React DOM,React Native,React DOM Server,这里的复用有两种思路:

  1. 让用户把 renderer 作为一个参数传递给 hox,例如 createGlobalStore(hook, ReactDOM.render)
  2. 提供一个 HoxRoot 组件,让用户自己把这个组件渲染到页面上,这样 hox 就不需要关系怎么渲染自己了

综合考虑之后,我选择了第 2 种方案,因为开发者的体验会更好一些,理解成本也比较低,还能直接复用已有的生态(例如 next.js)自动选择渲染环境。

具体用法和 API 介绍

README

@awmleer awmleer requested a review from brickspert May 19, 2022 03:30
@awmleer awmleer self-assigned this May 19, 2022
@qiutian00
Copy link

赞赞赞

@awmleer awmleer mentioned this pull request May 19, 2022
@awmleer awmleer merged commit e76bdc3 into master May 24, 2022
@delete-merged-branch delete-merged-branch bot deleted the feat/2.0 branch May 24, 2022 02:04
@xiaoqiang1999
Copy link

好用,支持!

@xiaoqiang1999
Copy link

2.0应该再推广推广吧,这么好用,感觉知道的人并不多,相关文章也很少

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

Successfully merging this pull request may close these issues.

3 participants