reactjs - 如何构建通用打字稿自定义钩子?
问题描述
我有一个 React Hook,它以多种形式用于从 API 调用中获取数据。目标 URL 是使用挂钩的参数定义的。返回的对象可能是几种类型之一,具体取决于使用钩子的组件,我在下面包含了一个摘录:
export const useFormControl = (
feature: Feature,
id?: string,
) => {
const [{ data, error, loading}] = useAxios({
url: `https://this.is.the.url?feature=feature&id=id`,
});
...
return {
data,
error,
loading,
...
} as const;
};
我正在使用如下效果:
const FormType1 = {
prop1 : string;
prop2: string
}
export const Form = ({ ... }: FormProps) => {
const [formData, setFormData] = useState<FormType1>();
const {
data,
error,
loading,
...
} = useFormControl(mode,id);
useEffect(() => {
if (data) {
setFormData(data as FormType );
}
}, [formData]);
// use formData here...
}
这种模式重复了很多次。我宁愿不必在每个组件中都有一个 useEffect 使用钩子将传入的数据转换为该表单的 FormType。有没有办法使用泛型来“键入”自定义钩子,以便 useAxios 钩子的数据可以是正确的类型?
解决方案
我在这里使用答案解决了这个问题:Custom Hook with Generic Types TypeScript
将钩子更改为具有类型化接口的函数。
interface ReturnedData<TResponse> {
data: TResponse;
error: AxiosError<any> | undefined;
loading: boolean;
...
}
export function useFormControl<T> = (
feature: Feature,
id?: string,
):ReturnedData<T> => {
const [{ data, error, loading}] = useAxios<T>({
url: `https://this.is.the.url?feature=feature&id=id`,
});
...
return {
data,
error,
loading,
...
} as const;
};
然后用作:
const {
data,
error,
loading,
...
} = useFormControl<FormType>(mode,id);
推荐阅读
- c++ - Compiling Qt projects in Qt/MsBuild format without Qt VS Tools installed
- html - 为什么我不能用边界半径做一个圆?
- html - 声明 CSS 类的正确方法是什么?与以下方法有什么不同?
- osgi - MANIFEST 文件是如何在我的 AEM osgi 包中生成的?
- twitter-bootstrap - 带有 vue.js 的垂直 Tab 引导程序的错误输出
- javascript - 加载图像时的触发方法(Internet Explorer)
- java - ZipException:转换重复条目 com/google/android/gms/internal/zzez.class
- ruby-on-rails - 在 Rails api 应用程序中使用“ApplicationController.new.render_to_string”(config.api_only = true)
- ios - 日期不是使用 DateFormatter 从字符串创建的
- c# - 未连接到 Azure Active Directory 的 Office 365 API