当前位置: 首页 > news >正文

花都做网站公司海南百度竞价排名

花都做网站公司,海南百度竞价排名,免费用的云服务器,外贸seo网站搭建在页面上 loading(加载)的效果十分常见,在某些场景下,一个页面上甚至可能有特别多的 loading 存在,此时为每一个 loading 专门创建一个 state 显然太过繁琐,不如试试写一个 useLoading 来集中管理&#xff…

在页面上 loading(加载)的效果十分常见,在某些场景下,一个页面上甚至可能有特别多的 loading 存在,此时为每一个 loading 专门创建一个 state 显然太过繁琐,不如试试写一个 useLoading 来集中管理!

构思分析

状态形式

当页面上有众多的 loading 时,我们需要能区分它们,因此 useLoading 存储的 state 应当是 KV 式 或者数组式,KV 更方便,我们将采用 KV 式,K 代表 loading 的标识名称,V代表是否 loading。

返回形式

useLoading 应当提供哪些 api 呢?返回 state 和 setState 是必要的,此外,提供根据 K 的 setLoading 以及 根据 K 的 onloading 和 unloading 也是 非常使用的。

初始化方式

既然已经确定了 state 为 KV 式,初始化给个对象即可。

代码实现

接口和类型声明

声明 UseLoading 的入参为初始 state ,并定义其为泛型,默认为 Record<string, Boolean>,并按照 useHooks 的习惯,返回一个 只读 的数组,第一项为 state,第二项为 set,第三项为 onloading,第四项为 unloading。
此外,我们需要为 set 额外定义一个接口,用于 (K,V)({k,v}) 两种入参形式的函数重载。

export interface SetLoading<T = Record<string, Boolean | number>,K extends keyof T  = keyof T
> {(key: K, value?: boolean): void;(key: K, setAction: (pre: boolean | number)=> boolean): void;(state: Record<K, boolean>): void;(setAction: (pre: T) => T): void;
}export interface UseLoading<T = Record<string, boolean>> {(loadingMap: T): readonly [T,SetLoading,(key: keyof T) => void,(key: keyof T) => void];
}
具体实现
export const useLoading: UseLoading = <T = Record<string, boolean | number>>(initialLoadingMap: T
) => {const [loading, _setLoading] = useState<T>(initialLoadingMap);const setLoading: SetLoading<T, keyof T> = (args1 , value = true) => {if (typeof args1 === "object") {_setLoading((pre) => ({ ...pre, ...args1 }));return;} else if (typeof args1 === "function") {_setLoading((pre) => args1(pre));return;} else {const key = args1;if (typeof value === "function") {_setLoading((pre) => ({ ...pre, [key]: value(pre[key]) }));} else {_setLoading((pre) => ({ ...pre, [key]: value }));}}};const onLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: true }));};const unLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: false }));};return [loading,setLoading,onLoading,unLoading,] as unknown as ReturnType<UseLoading>;
};

到这里,基础的 useLoading 就实现了,以下是简单的使用示例:

export default function Demo(){const [loading, setLoading] = useLoading({button1: false,button2: false,})const handleClick = (key: 'button1'|'button2') => {setLoading()}return(<><button onClick={() => setLoading('button1')}>{loading.button1? 'loading':'button1'}</button><button onClick={() => setLoading('button1')}>{loading.button2? 'loading':'button2'}</button></>)
}

进阶

有时候,我们的 loading 只是效果,并不阻止用户操作,那么当用户连续进行点击等操作时,我们希望 loading 效果应当延续下去,此时只使用上面的 useLoding 显然乏力,我们需要额外维护一个具有计数性质的 state(数字数组,Promise数组等) 配合使用,这将使代码变得异常臃肿。

换位思考一下,我们需要计数的特性,useLoding 使用的 state 是 Boolean,那么有没有办法可以同时兼备布尔值和数字的特性呢?在 JS/TS 中,boolean 本身就支持加减操作,加减后会隐式转换为数字,答案已经呼之欲出了!允许我们的 useLodng 使用数字作为每个 loading 的值,即可完美的升级 useLoading,并完全兼容基础版的 useLoading,我们只需要做一些小小的改变:

接口和类型声明

在这里,将 boolean 都替换为 boolean | number 即可。
其次,我们提供了2个额外的 api:plusminus,即递增和递减。
此外,我还为 useLoading 新加了一个 returnType 入参的重载,因为有些人可能更偏爱对象而不是数组,比如笔者自己。

export interface UseLoading<T = Record<string, boolean | number>> {(loadingMap: T): readonly [T,SetLoading,(key: keyof T) => void,(key: keyof T) => void,(key: keyof T) => void,(key: keyof T) => void];(loadingMap: T, returnType: "object"): Readonly<{values: T;set: SetLoading;on: (key: keyof T) => void;un: (key: keyof T) => void;plus: (key: keyof T) => void;minus: (key: keyof T) => void;}>;
}export interface SetLoading<T = Record<string, boolean | number>,K extends keyof T = keyof T
> {(key: K, value?: boolean | number): void;(key: K, setAction: (pre: boolean | number) => boolean | number): void;(state: Record<K, boolean | number>): void;(setAction: (pre: T) => T): void;
}
代码实现

在这里,实现上与 基础的 useLoading 几乎完全相同,只是多了几个新的返回和一套对象形式的返回。

// @ts-ignore
export const useLoading: UseLoading = <T = Record<string, boolean | number>>(loadingMap: T,returnType: "array" | "object" = "array"
) => {const [loading, _setLoading] = useState(loadingMap);const setLoading: SetLoading<T, keyof T> = (args1, value = true) => {if (typeof args1 === "object") {_setLoading((pre) => ({ ...pre, ...args1 }));return;} else if (typeof args1 === "function") {_setLoading((pre) => args1(pre));return;} else {const key = args1;if (typeof value === "function") {_setLoading((pre) => ({ ...pre, [key]: value(pre[key]) }));} else {_setLoading((pre) => ({ ...pre, [key]: value }));}}};const onLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: 1 }));};const unLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: 0 }));};const plusLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: (pre[key] as number) + 1 }));};const minusLoading = (key: keyof typeof loading) => {_setLoading((pre) => ({ ...pre, [key]: (pre[key] as number) - 1 }));};if (returnType === "array") {return [loading,setLoading,onLoading,unLoading,plusLoading,minusLoading,] as const;} else {return {values: loading,set: setLoading,on: onLoading,un: unLoading,plus: plusLoading,minus: minusLoading,} as const;}
};

现在,一个进阶版的 useLoading 就完成了,你完全可以把它当作普通的 useLoading 穿 boolean 用,如果有计数的需要你就可以把它当数字用:

function sleep<T>(time: number) {return new Promise<void>(function (resolve) {setTimeout(() => {resolve();}, time);});
}export default function Demo(){const { values: loading, plus, minus } = useLoading({ button1: false }, 'object');const click = async () => {plus('button1')await sleep(1000);minus('button1')}
}return(<><button onClick={click}>{loading.button1? 'loading':'button1'}</button></>)
}
http://www.shuangfujiaoyu.com/news/7895.html

相关文章:

  • 赶集的网站怎么做seo发外链的网站
  • 上海高端建站网站外链网盘系统
  • 阿里云虚拟主机怎么建设网站网络营销的内容主要有哪些
  • 寻找杭州做网站软件人选择宁波seo优化公司
  • 哪个网站可以接任务做兼职网站测试的内容有哪些
  • wordpress改成手机号注册冯耀宗seo博客
  • 传统网站网站开网站需要什么流程
  • 建个网站怎么让香港客户看到电商网站规划
  • 网站建设广州公司公司网站建设全包
  • 济南网站托管运营百度发布信息怎么弄
  • 商洛网站建设哪家好网站移动端优化工具
  • 推广营销软件seo优化与品牌官网定制
  • 微信授权登录第三方网站开发定制型营销网站建设
  • 什么是h5网站开通网站需要多少钱
  • 大连专业手机自适应网站建设维护百度灰色关键词排名
  • 什么网站是专门做艺术字的百度总部投诉电话
  • 动态ip做网站可以备案吗百度一下官网手机版
  • 做网站 就上宝华建站谷歌seo推广服务
  • 东莞百度代做网站联系方式百度怎么发帖子
  • 做高铁在哪个网站买seo模拟点击软件源码
  • 水果套餐网站重庆百度推广排名
  • 网站建设需要哪个部门审批网站制作流程是什么
  • 电商网站建设分析免费建站的网站有哪些
  • 免费做祝福网站网站制作建设
  • 南通网站设计制作网站模板中心
  • 开发区税务局办税大厅电话河北seo网络优化师
  • 网站空间200m哪个好用?
  • 企业站官方网站日本和韩国是亚洲的国家
  • 邵阳网站建设的话术做百度推广销售怎么样
  • 石家庄网站开发公司电话体球网足球世界杯