前言:
今天咱们对“jquery怎么传掺给函数”大约比较关注,大家都需要知道一些“jquery怎么传掺给函数”的相关文章。那么小编也在网上汇集了一些对于“jquery怎么传掺给函数””的相关文章,希望你们能喜欢,你们一起来了解一下吧!文章来自公众号@支付宝体验科技,
前言
目前小程序开发中,React 技术栈是主流,大部分人都在使用“类 Class 组件”开发小程序,即通过声明一个对象,使用各种生命周期来开发一个组件,最典型的是支付宝 AppX 框架以及微信小程序,我们也叫原生小程序。当然,也有部分是使用“ Hooks ”开发组件的,比如 Remix 等。
Class 组件和 Hooks 组件各有优缺点。
Class 组件的问题在于组件之间复用状态逻辑很难、复杂组件变得难以理解、难以理解的 Class,这些是 React 官网的原话,相信有过编写 Class 经验的人都知道。
Hooks 的问题在于上手门槛高了,你必须对 React 和 Hooks 有更深刻的理解,否则很容易写出 bug 。
遥想当初我们使用 jQuery 一把梭哈的时候,是不是很简单?是不是很单纯?不用理解那么多的造出来的概念,回归到最原始的以解决问题为目标的编程。
本文提出一种小程序开发方法,可以让你以 jQuery 函数式编程风格开发小程序。
先看 demo
,时长00:33
调用方代码:
上面是一个典型的交互组件:弹窗输入框组件:
1. 我们通过 this.hook(componentName) 拿到输入框组件实例。
2. 输入框组件提供一个 show() 函数,用于显示弹窗。
3. 用户在输入框里面编辑、修改内容,然后点击完成按钮。
4. show() 函数同步返回输入框的值。对输入框组件来说,我们只关心它的返回值。
5. 最后我们把用户输入的值通过 setData 显示在页面上,再通过 close() 方法关闭弹窗。
可以看到,上面的代码调用一个输入框组件,就和 jQuery 组件一样,通过函数就能完成。
那么我的 AXML 应该怎么写呢?很简单,AXML 只需要一行:
只需要在第10行声明一下组件的名称 componentName 就行了,然后你就可以通过 hook(componentName) 拿到这个组件的实例了。任何函数式组件都只需要一行就可以搞定。
那么又会问了,这个 inputPopup 组件是怎么写的呢?很简单,小程序怎么写组件就怎么写,来看代码:
组件的代码有点多,没关系,我们来分析下:
这是一个标准的小程序写法,没有创造新的语法和DSL,大家应该很熟悉。
我们先来看入口,组件提供的 show 和 close 方法就是在 install 生命周期里面返回的。install 生命周期在小程序初始化时执行,整个小程序应用周期内只执行一次,它应该返回一个对象,这个对象就是组件实例的值,也就是说组件返回什么值,调用方拿到的就是什么值。
我们的组件返回了 show 和 close 2个函数,所以我们可以通过 input.show 来调用它。
那么当我调用 input.show 时发生了什么呢?很简单,它就是 JavaScript 的函数调用。可以看到 show 和 close 就是组件的2个属性,它和小程序的 methods 完全一样,你可以在函数里面通过 this 访问实例,通过 setData 触发视图响应。
现在你明白了吗?页面和组件的通信不再是 React 的 Props 了,也不再是 React Hooks 了,而是原生的 JavaScript 函数调用。
这就是小程序函数式调用组件。
这意味着什么?
函数式调用组件是什么东西?它本质上是一种设计模式,就和 Class 组件以及 React Hooks 一样,你也可以理解为它是另一种组件间通信方案。
正如 React Hooks 里面介绍的一样,请记住函数式调用组件是:
完全可选的。 你无需重写任何已有代码就可以在一些组件中尝试函数式组件。100% 向后兼容的。 函数式组件不包含任何破坏性改动。它没有创造新的语法和DSL,它完全运行在原生小程序之上。现在可用。 函数式组件已经发布,并且已经在线上运行1年多了。
它和 Class 组件以及 React Hooks 有什么优点?
如果你认真的看了上面的demo,你就会发现它的优点。它在设计之初,就是为了解决 Class 和 React Hooks 的问题:Class组件写起来麻烦且很难维护。React Hooks 上手门槛高且更复杂。
下面我们分析下函数式组件如何解决上面的问题:
先说和 Class 对比
Class 组件最大的问题在于各种生命周期,其中最令人头疼的是componentDidUpdate。它让复杂组件变得无法阅读和维护,试想一下,当你编写一个复杂交互的组件时,它接受 N 个 Props 可选项,然后在 componentDidUpdate里面一堆的比较代码,就为了找出哪个 Props 变更了。
我曾经维护过一个 h5 数字键盘组件,当其中一个 Props 变更时,它就像一片雪花引起雪崩一样,你不知道下一个状态会是什么。
componentDidUpdate另一个致命的问题是:新手经常会写出死循环的代码。
函数式组件如何解决?
既然componentDidUpdate 的设计模式让问题变得复杂,那我们就不用它,把它干掉。所以函数式组件里面没有这种循环的生命周期。它和组件之间的通信就是通过原生的 JavaScript 函数调用,使用函数入参来代替 Props。函数调用我们已经非常熟悉了,它的行为是明确的,它让我们的代码执行流程变得有章可循。
函数入参带来的另一个好处是:它让我们的 data 保持干净。
试想一下你的组件有 10个 Props 来控制行为,你的 data 里面就必须有 10 个额外的字段,这本来是没必要的,因为它们仅仅是临时变量。
再说和 React Hooks 对比
React Hooks 干掉了 Class 和 生命周期,也干掉了 componentDidUpdate,它让组件完全由 JavaScript 函数编写,函数入参就是 Props,这看起来和我们刚刚说的函数式调用组件是一样的。
但它在解决 Props 更新的问题上,又选择了重复执行的方式,也就是说,我们的 Hooks 组件又回到了无限循环执行的噩梦中。重复执行对 Props 来说是正确的,因为我们的组件永远应该渲染最新的 Props。但其它应该保持引用的变量却不能重复创建。
然后为了解决重复执行带来的变量无法保持引用的问题,又带来了 useState,useCallback 等,就是这些东西让我们的 Hooks 组件变得难以理解。你必须要理解 Hooks 的原理,否则很容易写出 bug 或者存在性能问题的组件。
函数式组件如何解决?
和 React Hooks 一样,我们选择用函数调用来代替 componentDidUpdate,用函数入参来代替 Props。但在如何更新 Props 上,函数式组件选择了使用额外的函数调用来解决重复调用的问题。
为什么要这样设计呢?Class 的好处是拥有实例状态,它可以很方便的让我们保存和读取需要引用的变量,为了弥补componentDidUpdate 带来的问题,我们以明确的函数调用来替换由 Props diff 触发的调用。
仅仅是一个微小的改动,函数式组件让 Class 和 Hooks 的优点结合在一起。你可能会说这是四不像,又有 Class 又有 Hooks 的思想在里面,那你这个到底是什么东西。
它就是函数式调用组件。实际好不好用,还得在实践中证明。
至少,它让我在开发复杂交互组件时,不必浪费时间在调试组件间通信问题,也不必浪费时间在如何管理 Props 以及 diff 上,我只要考虑哪些部分代码应该放在组件里。即使时隔一年,我再回过来看复杂交互的组件代码,我也能很快清晰的整理出它的执行流程。
再BB两句我再啰嗦几句:函数式调用组件完全是在原生小程序之上构建的,它运行在运行时,而不是构建时,它没有破坏小程序现有规则,也不依赖任何框架,它可以和原生小程序共用。
最后BB两句
函数式组件灵感来源于真实业务中,当初是为了解决小程序中大量的复杂交互,很多交互都是带有 RPC 请求的,并且还涉及到缓存、并发、时序问题,这样增加了小程序开发难度,尤其是小程序中涉及到输入框的,相信深度研究过小程序输入框的都被它折磨过。这其中有大量的交互会复用在各个页面中,自然我们想把它作为一个组件复用,但写 Class 组件实在是让我们心力交瘁,一个是项目时间紧,基本倒排,另一个是复杂度和可维护性。
所以我们就想,一个带有交互的组件,它的行为触发一定是明确的,就好像我们想要调用一个模块或者一个系统时,它提供一个 API,提供入参,然后我们调用它,它处理后返回结果给我们。这就是函数调用,UI 交互一定是因为某一个明确的事件触发,可以是一个点击事件,一个长按事件,一个明确的事件触发一个明确的函数调用,函数里面处理交互的结果。声明式的思想适合不带交互的UI组件,或者是交互结果明确能执行的组件,如果遇到交互结果可能会被回滚的情况,声明式组件如何表示声明被撤销的情况呢?
标签: #jquery怎么传掺给函数