热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

hooks组件封装react_名符其实的react下一代状态管理器hox

自从React16版本发布Hooks以来,大家纷纷上车尝鲜。毫无疑问,Hooks在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻

自从 React16 版本发布 Hooks 以来,大家纷纷上车尝鲜。毫无疑问, Hooks 在一定程度上解决了组件间功能和逻辑复用的问题,在组件间的逻辑的封装和复用确实真香,但 Hooks 在数据状态的共享方法略有不足,虽然可以使用 useReducer 实现数据状态管理,但在一定程度上是对 redux 的思想的复用。我们知道 redux 、 Flux 、 dva 等这些 React 状态管理的工具,实际上都是对 action 、 dispatch 、 reducer 、 useStore 、 Provider 、 Context 这些概念的排列组合,概念太多,学习入手成本较高,项目使用都差不多,会有产生许多的模版代码。

hox

既然如此是否有学习成本比较低,入手简单的针对 Hooks 的状态管理器呢?答案是有,其中来自来自蚂蚁金服体验技术部 hox 就是这样一种工具。下面我们从学习、上手、原理几个方法聊聊这个被定为为下一代 React 状态管理器,看看其是否符合其定位的目标。

学习

hox 来自蚂蚁金服体验技术部,其背后的团队在 React 各种实践场景上都有很丰富的经验,因此其后续的维护和迭代还是很靠谱的。可能因为其只有一个 API ,因此其文档也是十分简单的,一眼就能看到头了。这对于我们前端的开发者而言就是很友好的,由于千变万化的前端,各种轮子、各种技术层出不穷,前端的娃娃们表示学不动了。而这种只有一个 API 的工具,我们表示还是可以学的动的。 hox 的详细文档可以参看 github 上的 readme 支持中英文,链接如下:

  1. 中文文档 : github.com/umijs/hox/b…
  2. 英文文档 : github.com/umijs/hox/b…

特性

hox 作为下一代的状态管理器,其具有如下特性:

  1. 只有一个 API,简单高效,几乎无需学习成本
  2. 使用 custom Hooks 来定义 model,完美拥抱 React Hooks
  3. 完美的 TypeScript 支持
  4. 支持多数据源,随用随取

上手

hox 的上手使用体验还是很不错的,因为十分简单。talk is cheap,show me code。我们直接上码看看。

import { useState } from "react";import { createModel } from "hox";function useCounter() { const [count, setCount] = useState(0); const decrement = () => setCount(count - 1); const increment = () => setCount(count + 1); return { count, decrement, increment };}export default createModel(useCounter);

import useCounterModel from "../models/counter";function App(props) { const { count, increment, decrement } = useCounterModel(); return (

{count}

Increment Decrement
);}

使用 hox 就是这么简单,通过 createModel 包装一下将 custom hook 变成 share hook ,就可以在各个组件之间共享数据状态,并实现逻辑封装和复用。

原理

createModel 会创建一个 Executor 组件的实例,并在执行 custom hook , custom hook 的执行结果会被保存起来。最后,它会返回一个新的 share hook 即是 model hook 实现数据和逻辑的共享。源码如下:

import { ModelHook, UseModel } from "./types";import { Container } from "./container";import { Executor } from "./executor";import React, { useEffect, useRef, useState } from "react";import { render } from "./renderer";export function createModel(hook: ModelHook, hookArg?: P) { // 实例化一个容器,通过发布订阅模式实现对状态改变的推送 const container = new Container(hook); // 实例化 Executor 组件,当数据发生改变时,notify 所有订阅者进行更新 render( { container.data = val; container.notify(); }} hook={() => hook(hookArg)} /> ); // useModel 这是 share hook const useModel: UseModel = depsFn => { const [state, setState] = useState(() => container ? (container.data as T) : undefined ); const depsFnRef = useRef(depsFn); depsFnRef.current = depsFn; const depsRef = useRef([]); useEffect(() => { if (!container) return; function subscriber(val: T) { if (!depsFnRef.current) { setState(val); } else { const oldDeps = depsRef.current; const newDeps = depsFnRef.current(val); if (compare(oldDeps, newDeps)) { setState(val); } depsRef.current = newDeps; } } container.subscribers.add(subscriber); return () => { container.subscribers.delete(subscriber); }; }, [container]); return state!; }; // share hook 代理 custom hook 返回的值 Object.defineProperty(useModel, "data", { get: function() { return container.data; } }); return useModel;}// 这是 hook 依赖项对比函数function compare(oldDeps: unknown[], newDeps: unknown[]) { if (oldDeps.length !== newDeps.length) { return true; } for (const index in newDeps) { if (oldDeps[index] !== newDeps[index]) { return true; } } return false;}

其原理图如下:

e3308f342cec21d4c3a7e979e12121fd.png

总结

简言之, hox 大道至简,只有一个 API ,但其既能满足逻辑的封装和复用,又能满足状态复用和管理,值得尝试的状态管理器。



推荐阅读
author-avatar
小谢blue
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有