背景
项目中要封装一个可以解析url query params
的hook。
前提
已知react-router-dom
中的useSearchParams
,传入对应的key值可以帮助我们快速解析url中queryParams。
useSearchParams使用示例
例如: http://xxx.com?name=cc&age=18
,利用useSearchParams
可以帮我们解析对应的。
const [searchParams] = useSearchParams();
searchParams.get(name); // cc
目标
实现一个useUrlQueryParams
,通过传入对应的key值组成的数组keys
,返回对应key值解析后组成的对象。
/**
* @param {string[]} keys
* @return {object}
*/
const useUrlQueryParams = (keys: string[]) => {
const [searchParams] = useSearchParams();
return keys.reduce(
(pre, next) => ({ ...pre, [next]: searchParams.get(next) }),
{}
);
};
改进
存在的问题
实现的useUrlQueryParams
,虽然能正常使用,但在解构时并没有很好的体验,代码没根据输入进行提示。
// 输入xx时并不会提示有name,age等key值
const { xx } = useUrlQueryParams(["name", "age"]);
改进后的两种useUrlQueryParams
写法:
export const useUrlQueryParams = <T extends string>(keys: T[]) => {
const [searchParams] = useSearchParams();
return keys.reduce<Partial<{ [K in T]: string }>>(
(pre, next) => ({ ...pre, [next]: searchParams.get(next) || '' }),
{}
);
};
export const useUrlQueryParams = <T extends string>(keys: T[]) => {
const [searchParams] = useSearchParams();
return keys.reduce(
(pre, next) => ({ ...pre, [next]: searchParams.get(next) || '' }),
{} as { [K in T]: string }
);
};
实现过程
- 定义泛型T,由类型推断,可以让T得到由key值组成的联合类型(例如
"name" | "age"
) - 利用
in
遍历T,保证返回对象的key值为输入值keys中的值 - 由于
reduce
遍历时传入的初始值为{}
,为了防止错误提示,可以利用Partial
来规避掉初始值的错误提示,或者使用{} as {[K in T]: any}