从 custom Hooks 到 shared Hooks :hox 原理分析

2019-11-01 admin

本文旨在用尽可能通俗易懂的方式讲清楚 hox 在底层是如何实现的,也因此可能在某些方面的表述不够严谨,如有偏颇,还请各位读者多多指正。

Hox 是下一代的 React 状态管理器,关于它的更多介绍可以参考这篇文章,本文假设你已经对 hox 的用法有了初步的了解。

在 hox 中,我们希望能充分发挥 React Hooks 的特性,也希望让全局状态和组件内部状态的编写体验保持一致,所以我们使用 custom Hook 的方式定义 model 的逻辑。

我们不妨先来看下一个普通的 custom Hook 是什么样的效果吧:

export function useFoo() {
  const [count, setCount] = useState(0)
  function increment() {
    setCount(count + 1)
  }
  return {
    count,
    increment,
  }
}

我们可以在组件中调用 useFoo

export function ComponentA() {
  const foo = useFoo()
  return (
    <div>
      <p>{foo.count}</p>
      <button onClick={foo.increment}>Increment</button>
    </div>
  )
}

不难发现,我们通过定义 custom Hook ,对逻辑进行了一层封装,也让组件变得更加简洁。然而,如果此时我们再创建一个 B 组件:

export function ComponentB() {
  const foo = useFoo()
  return (
    <div>
      <p>{foo.count}</p>
    </div>
  )
}

当我们点击 A 组件中的 Increment 按钮时,B 组件中的数字会跟着变化么? 答案自然是不会的,因为 useFoo 这个 custom Hook 虽然实现了逻辑的封装复用,但是却并不能让数据共享

而 hox ,就是为了解决这个问题而生。

我们不妨接着上面的例子,使用 hox 提供的 createModeluseFoo 进行一层封装:

const useFooModel = createModel(useFoo)

createModel 会创建一个 Executor 组件的实例,并在其中执行 useFoo 这个 Hook ,并把 useFoo 的执行结果保存起来。最后,它会返回一个新的 Hook: useFooModel 。乍一看, createModel 和 HOC (高阶组件)甚至有几分神似。

不同于 useFoo ,在调用 useFooModel 时,我们并不是真的执行了 useFoo 这个 custom Hook ,而是向 Executor 组件进行数据的订阅。也就是说,如果我们在多个组件中都调用了 useFooModel ,那它们所拿到的数据实际上是同一份,更准确的说,它们拿到的那份数据,就是存在 Executor 中的那份 state

通过这种方式,我们让 custom Hook 可以做到数据的共享,这也是 createModel 之所以叫做 createModel 的原因:通过它,我们把一个 custom Hook 变成了一个全局的 model 。

现在,我们再来更新一下刚才的例子:

export function ComponentA() {
  const foo = useFooModel() // 这里从 useFoo 变成了 useFooModel
  return (
    <div>
      <p>{foo.count}</p>
      <button onClick={foo.increment}>Increment</button>
    </div>
  )
}

export function ComponentB() {
  const foo = useFooModel() // 这里从 useFoo 变成了 useFooModel
  return (
    <div>
      <p>{foo.count}</p>
    </div>
  )
}

现在,A B 两个组件都获取到了 Executor 中的那份数据,并且订阅了它未来的更新。因此当我们点击组件 A 的 Increment 按钮时,我们实际上是触发了 Executor 组件中的一个 setState ,然后 Executor 组件进行重渲染,通知它的订阅者们。A 组件和 B 组件收到了更新通知和新的数据,也会跟着重新进行渲染。最终我们可以看到,A B 两个组件显示的数字都变成了 1

如果你希望对 hox 有更多的了解的话,不妨在 GitHub 上阅读它的源码,或是亲自体验一下~

[转载]原文链接:https://segmentfault.com/a/1190000020873308

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-78744.html

文章标题:从 custom Hooks 到 shared Hooks :hox 原理分析

相关文章
游戏机遇到来 非主流HTML5能否成器?
2014年第四季度以来,有60%的游戏行业从业者已经投入或准备投入开发HTML5为基础的游戏,并对其前景表示乐观的态度。   对HTML 5这项诞生于2008年的标准来说,其正在经历最好的时代。 游戏机遇到来 非主流HTML5能否成器?  ...
2015-11-12
Webpack(含 4)配置详解——从 0 配置一套开发模板
前言 源代码 熟悉 webpack 与 webpack4 配置。 webpack4 相对于 3 的最主要的区别是所谓的零配置,但是为了满足我们的项目需求还是要自己进行配置,不过我们可以使用一些 webpack 的预设值。同时 webpack...
2018-05-02
Vue.js原理分析之observer模块详解
介绍 observer是Vue核心中最重要的一个模块(个人认为),能够实现视图与数据的响应式更新,底层全凭observer的支持。 **注意:**本文是针对Vue@2.1.8进行分析 observer模块在Vue项目中的代码位置是src/c...
2017-03-16
node.js读取文件到字符串的方法
本文实例讲述了node.js读取文件到字符串的方法。分享给大家供大家参考。具体分析如下: Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始。比较独特的是,Node.js会假设你是在POSIX环境...
2017-03-27
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
大家在做些页面的时候,很多都是用ajax实现的,在显示的时候有很多表单提交的add或者update操作,显然这样很烦,突然想到了一个比较好的方法,下面给大家分享下如何用js 实现依赖注入的思想,后端框架思想搬到前端来。 应用场景: 前后端一...
2017-03-29
深入理解JavaScript的React框架的原理
如果你在两个月前问我对React的看法,我很可能这样说: 我的模板在哪里?javascript中的HTML在做些什么疯狂的事情?JSX开起来非常奇怪!快向它开火,消灭它吧! 那是因为我没有理解它. 我发誓,React 无疑是在正确的轨道...
2017-03-26
javascript动画算法实例分析
本文实例讲述了javascript动画算法。分享给大家供大家参考。具体如下: 动画算法 Linear:无缓动效果(匀速运动); Quadratic:二次方的缓动; Cubic:三次方的缓动 Quartic:四次方的缓动; Quintic:五...
2017-03-27
javascript实现倒计时(精确到秒)
代码相当简单实用,这里就不多废话了,小伙伴们简单看下就能明白 &lt;!DOCTYPE html PUBLIC &quot;-&#x2F;&#x2F;W3C&#x2F;&#x2F;DTD XHTML 1.0 Transitional&#x2...
2017-03-25
深入分析JSON编码格式提交表单数据
以JSON编码格式提交表单数据是HTML5对WEB发展进化的又一大贡献,以前我们的HTML表单数据是通过key-value方式传输的服务器端,这种形式的传输对数据组织缺乏管理,形式十分原始。而新出现的JSON格式提交表单数据方法,将表单里的...
2017-03-25
JavaScript实现滑动到页面底部自动加载更多功能
话不多说,请看代码: &#x2F;&#x2F;滚动条到页面底部加载更多案例 $(window).scroll(function(){ var scrollTop = $(this).scrollTop(); &#x2F;&#x2F...
2017-03-17
回到顶部