对于helux
helux是一个激励服务注入,并反对响应式变更react的全新数据流计划,它的前身是concent(一个类vue开发体验的高性能状态治理框架),但concent本身因为须要兼容class和function保持一致的语法,且为了对其setup
性能,导致外部代码量切实太大,压缩后有70
多kb,api裸露得也十分多,导致学习难度急剧回升,为了更合乎当初十分风行的DDD
围绕业务概念构建畛域模型的编码趋势,helux
一开始就设计为激励服务注入
、反对响应式变更
、反对依赖收集
的轻量级react数据流计划。
它领有以下劣势:
- 轻量,压缩后2kb
- 简略,仅裸露6个api
- 高性能,自带依赖收集
- 响应式,反对创立响应式对象,在视图之外变更对象将同步更新视图
- 服务注入,配合
useService
接口轻松管制简单业务逻辑 - 状态晋升0改变,所以中央仅需将
useObject
换为useSharedObject
即可晋升状态共享到其余组件 - 防止forwordRef 天堂,内置的
exposeService
模式将轻松解决父掉子时的ref
转发艰涩了解问题和传染性(隔代组件须要层层转发) - ts敌对,100% ts 编写,为你提供全方位类型提醒
为什么起名helux
,尽管心田上我是把它作为concent
v3版本去开发的,但因为它的变动切实太大,除了依赖收集不继承任何concent
的个性,同时它也是随同我开发的hel-micro诞生一款作品,我冀望它成为 hel-micro 生态的 luxury 级别的奉献,就将 hel-micro 和 luxury 两个词拼一起成为了 helux
。
欢送点星关注helux,它尽管较新,但已在我本人的应用场景中施展功不可没的作用,现已退出hel-micro生态大仓,期待能成为你违心筛选的一款可心数据流计划。
疾速上手
极致的简略是helux最大的劣势,理解以下6个api后,你能够轻松应酬任何简单场景,最大的魅力在于useSharedObject
和useService
两个接口,且看如下api介绍
以下所有api均对应有在线示例1和示例2,欢送fork并批改体验。
useObject
应用 useObject 有两个益处
- 1 不便定义多个状态值时,少写很多 useState
- 2 外部做了 unmount 判断,让异步函数也能够平安的调用 setState,防止 react 呈现正告 :
"Called SetState() on an Unmounted Component" Errors
// 基于对象初始化一个视图状态const [state, setState] = useObject({a:1});// 基于函数初始化一个视图状态const [state, setState] = useObject(()=>({a:1}));
useForceUpdate
强制更新以后组件视图,某些非凡的场景能够应用它来做视图重刷新
const forUpdate = useForceUpdate();
createSharedObject
创立一个共享对象,可透传给 useSharedObject
,具体应用见 useSharedObject
// 初始化一个共享对象const sharedObj = createSharedObject({a:1, b:2});// 基于函数初始化一个共享对象const sharedObj = createSharedObject(()=>({a:1, b:2}));
createReactiveSharedObject
创立一个响应式的共享对象,可透传给 useSharedObject
// 初始化一个共享对象const [reactiveObj, setState] = createReactiveSharedObject({a:1, b:2});sharedObj.a = 111; // 任意中央批改 a 属性,触发视图渲染setSharedObj({a: 111}); // 应用此办法批改 a 属性,同样也能触发视图渲染,深层次的数据批改可应用此办法
useSharedObject
函数签名
function useSharedObject<T extends Dict = Dict>(sharedObject: T, enableReactive?: boolean): [ SharedObject<T>, (partialState: Partial<T>) => void,]
接管一个共享对象,多个视图里将共享此对象,外部有依赖收集机制,不依赖到的数据变更将不会影响以后组件更新
const [ obj, setObj ] = useSharedObject(sharedObj);
useSharedObject
默认返回非响应式状态,如须要应用响应式状态,透传第二位参数为true即可
const [ obj, setObj ] = useSharedObject(sharedObj);// now obj is reactive setInterval(()=>{ state.a = Date.now(); // 触发视图更新 }, 2000);
useService
函数签名
/** * 应用用服务模式开发 react 组件: * @param compCtx * @param serviceImpl */function useService<P extends Dict = Dict, S extends Dict = Dict, T extends Dict = Dict>( compCtx: { props: P; state: S; setState: (partialState: Partial<S>) => void; }, serviceImpl: T,): T & { ctx: { setState: (partialState: Partial<S>) => void; getState: () => S; getProps: () => P; };}
它可搭配useObject
和useSharedObject
一起应用,会创立服务对象并返回,该服务对象是一个稳固的援用,且它蕴含的所有办法也是稳固的援用,可平安办法交给其它组件且不会破会组件的pros比拟规定,防止懊恼的useMemo
和useCallback
脱漏相干依赖
搭配useObject
时
function DemoUseService(props: any) { const [state, setState] = useObject({ a: 100, b: 2 ); // srv自身和它蕴含的办法是一个稳固的援用, // 可平安的将 srv.change 办法交给其它组件且不会破会组件的pros比拟规定 const srv = useService({ props, state, setState }, { change(a: number) { srv.ctx.setState({ a }); }, }); return <div> DemoUseService: <button onClick={() => srv.change(Date.now())}>change a</button> </div>;}
搭配useSharedObject
时,只需替换useObject
即可,其余代码不必做任何扭转
+ const sharedObj = createSharedObject({a:100, b:2})function DemoUseService(props: any) {- const [state, setState] = useObject({ a: 100, b: 2 );+ const [state, setState] = useSharedObject(sharedObj);
getState 和 getProps
因 state
和 props
是不稳固的,所以服务外部函数取的时候需从srv.ctx.getState
或srv.ctx.getProps
// 形象服务函数export function useChildService(compCtx: { props: IProps; state: S; setState: (partialState: Partial<S>) => void;}) { const srv = useService<IProps, S>(compCtx, { change(label: string) { // !!! do not use compCtx.state or compCtx.state due to closure trap // console.log("expired state:", compCtx.state.label); // get latest state const state = srv.ctx.getState(); console.log("the latest label in state:", state.label); // get latest props const props = srv.ctx.getProps(); console.log("the latest props when calling change", props); // your logic compCtx.setState({ label }); } }); return srv;}export function ChildComp(props: IProps) { const [state, setState] = useObject(initFn); const srv = useChildService({ props, state, setState });} return ( <div> i am child <br /> <button onClick={() => srv.change(`self:${Date.now()}`)}> change by myself </button> <h1>{state.label}</h1>; </div> );
exposeService
当孩子组件props上透传了exposeService
函数时,useService
将主动透传服务对象给父亲组件,是一种比拟不便的逃离forwardRef
实现父调子的模式
import { ChildSrv, Child } from "./Child";function App() { // 保留孩子的服务 const childSrv = React.useRef<{ srv?: ChildSrv }>({}); const seeState = () => { console.log("seeState", childSrv.current.srv?.ctx.getState()); }; return ( <div> <button onClick={() => childSrv.current.srv?.change(`${Date.now()}`)}> call child logic </button> <Child unstableProp={`${Date.now()}`} exposeService={(srv) => (childSrv.current.srv = srv)} /> </div> );}
结语
helux
是把concent
外部精髓全副萃取提炼再加工后的全新作品,冀望能失去你的喜爱。❤️