您现在的位置是:亿华云 > 数据库
让我们一起聊聊封装一个管理 Url 状态的 Hook
亿华云2025-10-03 20:21:35【数据库】1人已围观
简介本文来讲下 ahooks 中的 useUrlState。通过 url query 来管理 state 的 Hook。useUrlState 的特殊在之前的架构篇中我们就提到,ahooks 这个项目是一
本文来讲下 ahooks 中的让们 useUrlState。
通过 url query 来管理 state 的起聊 Hook。
useUrlState 的聊封特殊在之前的架构篇中我们就提到,ahooks 这个项目是装个l状一个 monoRepo。它的管理项目管理是通过 lerna[1] 进行管理的。可以从官网以及源码中看到 useUrlState 是让们独立一个仓库进行管理的。
也就是起聊你必须单独安装:
npm i @ahooksjs/use-url-state -S我认为官方这么做的理由是 useUrlState 基于 react-router 的 useLocation & useHistory & useNavigate 进行 query 管理。所以你必须要安装 react-router 的聊封 5.x 或者 6.x 版本。但其实很多 React 项目都不一定使用 react-router。装个l状假如将这个 hook 内置到 ahooks 中的管理话,可能会导致包体积变大。让们
另外,起聊该 hook 是聊封依赖于 query-string 这个 npm 包的。使用这个包,装个l状我认为理由有以下几点:
一来是管理其功能强大,站群服务器支持很多的 options 选项,满足我们各类业务需求。二来它业内也比较成熟,避免重复造轮子。三来它的包体积也很小,没什么负担。我们主要用到它的 parse 和 stringify 方法,压缩后只有 2.4 k。通过示例简单介绍下,这两个方法:
qs.parse(string, [options])
qs.parse(?name=jim) // { name: jim}
qs.parse(#token=123) // { token: 123}
qs.parse(name=jim&name=lily&age=22) // { name: [jim, lily], age: 22}
qs.parse(foo[]=1&foo[]=2&foo[]=3, { arrayFormat: bracket});
//=> { foo: [1, 2, 3]}qs.stringify(object, [options])
qs.stringify({ name: jim, age: 22}); // age=22&name=jim
qs.stringify({ name: [jim, lily], age: 22}); // age=22&name=jim&name=lily
qs.stringify({ foo: [1, 2, 3]}, { arrayFormat: bracket});
//=> foo[]=1&foo[]=2&foo[]=3useUrlState 源码解析直接看代码,显示初始值部分。
第一个参数为初始状态,第二个参数为 url 的配置,包括状态变更时切换 history 的方式、query-string parse 和 stringify 的配置。通过 react-router 的 useLocation 获取到 URL 的 location 对象。react-router 兼容 5.x 和 6.x,其中 5.x 使用 useHistory,6.x 使用 useNavigate。queryFromUrl 是调用 query-string 的 parse 方法,将 location 对象的 search 处理成对象值。targetQuery 就是云服务器提供商处理之后的最终值-将 queryFromUrl 和初始值进行 merge 之后的结果。// ...
import * as tmp from react-router;
// ...
const useUrlState = (
// 初始状态
initialState?: S | (() => S),
// url 配置
options?: Options,
) => {
type State = Partial<{ [key in keyof S]: any }>;
const {
// 状态变更时切换 history 的方式
navigateMode = push,
// query-string parse 的配置
parseOptions,
// query-string stringify 的配置
stringifyOptions,
} = options || { };
const mergedParseOptions = { ...baseParseConfig, ...parseOptions };
const mergedStringifyOptions = { ...baseStringifyConfig, ...stringifyOptions };
// useLocation钩子返回表示当前URL的location对象。您可以将它想象成一个useState,它在URL更改时返回一个新值。
const location = rc.useLocation();
// https://v5.reactrouter.com/web/api/Hooks/usehistory
// useHistory 钩子可以访问用来导航的历史实例。
// react-router v5
const history = rc.useHistory?.();
// react-router v6
const navigate = rc.useNavigate?.();
const update = useUpdate();
const initialStateRef = useRef(
typeof initialState === function ? (initialState as () => S)() : initialState || { },
);
// 根据 url query
const queryFromUrl = useMemo(() => {
return parse(location.search, mergedParseOptions);
}, [location.search]);
const targetQuery: State = useMemo(
() => ({
...initialStateRef.current,
...queryFromUrl,
}),
[queryFromUrl],
);
// 省略部分代码
}接下来看 url 的状态设置:
首先是根据传入的 s 值,获取到新的状态 newQuery,支持 function 方式。根据不同的 react-router 的版本调用不同的方法进行更新。假如是 5.x 版本,调用 useHistory 方法,更新对应的状态。
假如是 6.x 版本,调用 useNavigate 方法,更新对应的状态。香港云服务器
通过 update() -useUpdate() 更新状态。// 设置 url 状态
const setState = (s: React.SetStateAction
const newQuery = typeof s === function ? s(targetQuery) : s;
// 1. 如果 setState 后,search 没变化,就需要 update 来触发一次更新。比如 demo1 直接点击 clear,就需要 update 来触发更新。
// 2. update 和 history 的更新会合并,不会造成多次更新
update();
if (history) {
history[navigateMode]({
hash: location.hash,
search: stringify({ ...queryFromUrl, ...newQuery }, mergedStringifyOptions) || ?,
});
}
if (navigate) {
navigate(
{
hash: location.hash,
search: stringify({ ...queryFromUrl, ...newQuery }, mergedStringifyOptions) || ?,
},
{
replace: navigateMode === replace,
},
);
}
};思考与总结工具库中假如某个工具函数/hook 依赖于一个开发者可能并不会使用的包,而且这个包的体积还比较大的时候,可以将这个工具函数/hook 独立成一个 npm 包,开发者使用的时候才进行安装。另外这种可以考虑使用 monoRepo 的包管理方法,方便进行文档管理以及一些公共包管理等。
很赞哦!(89935)
相关文章
- 400G和800G相干光传输标准最新进展
- 为什么起域名意义非凡?起域名有什么名堂?
- 当投资者经过第二阶段的认真学习之后又充满了信心,认为自己可以在市场上叱咤风云地大干一场了。但没想到“看花容易绣花难”,由于对理论知识不会灵活运用.从而失去灵活应变的本能,就经常会出现小赢大亏的局面,结果往往仍以失败告终。这使投资者很是困惑和痛苦,不知该如何办,甚至开始怀疑这个市场是不是不适合自己。在这种情况下,有的人选择了放弃,但有的意志坚定者则决定做最后的尝试。
- 主流搜索引擎显示的相关搜索项越多,越能积极反映该域名的市场价值。同时,被评估域名的搜索引擎显示结果不佳可能是由于以下两个原因:
- 市场需求低迷,韩国8英寸晶圆厂产能利用率降至50%以下
- 4、待所有域名查询结束后可在右侧点击导出结果,即可以excel的文件方式将查询到的结果导出。
- 用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。
- 个人域名转为公司需要什么条件?个人域名转为公司该怎么做?
- 报告:数据中心物理基础设施销售飙升
- 注册域名要了解几大点?新手有什么方式注册域名?
热门文章
站长推荐
如何为企业数据中心存储部署在边缘做好准备
便宜域名使用如何?小白可以买到便宜域名吗?
公司在注册域名时还需要确保邮箱的安全性。如果邮箱不安全,它只会受到攻击。攻击者可以直接在邮箱中重置密码并攻击用户。因此,有必要注意邮箱的安全性。
一下域名,看有没有显示出你所解析的IP,如果有,就说明解析是生效的;如果没有,就说明解析是不生效的。
超聚变亮相openEuler峰会,FusionOS助力联通云持续创新
(4) 使用何种形式的域名后缀对网页搜索影响不大,但域名后缀也需要考虑方便用户记忆
新手可以注册cc域名吗?cc域名有什么特点?
众所周知,com域名拥有最大的流通市场和流通历史。最好选择com域名,特别是在购买域名时处理域名。其次可以是cn域名、net域名、org域名等主流域名,现在比较流行的王域名和顶级域名,都是值得注册和投资的。