将所有相关钩子分组在一起的最佳实践是什么?



是否可以对react hooks进行分组?

我有几个相关的自定义钩子,例如useListProduct,useAddProduct。

过去,我可以将这些函数打包到对象类中,但不能打包到react组件类中。下面是一个对象类的源代码:

import {useAxios} from "./useAxios";
export class Product{
static useListProduct(){
let url="list product API URL";
return useAxios(null,"get",url);
}
static useAddProduct(product){
let url="list product API URL";
return useAxios(product,"post",url);
}
}

useAxios.js

import axios from "axios";
import { useEffect, useReducer } from 'react';
import { redirect } from "react-router-dom";
let reducer = (state, action) => {
let result = { ...state };
switch (action.type) {
case "updateData":
result.data = action.data;
result.isLoading = false;
break;
case "updateError":
result.error = action.error;
result.isLoading = false;
break;
default:
break;
}
return result;
}
export function useAxios(data, method, url, header, responseType) {
const [itemList, updateItemList] = useReducer(reducer, { data: undefined, error: undefined, isLoading: true });
useEffect(()=>{
let fetchApi = async () => {
let requestObj = { "method": method, "url": url }
if (method.toLowerCase() === "get") {
requestObj.params = data;
} else {
requestObj.data = data;
}
requestObj["responseType"] = responseType || undefined;
requestObj["headers"] = header || undefined;
try {
let result = await axios(requestObj);
updateItemList({ "data": result.data, type: "updateData" });
} catch (error) {
let errorObj;
if (error.response) {
switch (error.response.status) {
case 401:
alert(error.response.data);
redirect("/login");
break;
case 404:
errorObj = {
status: 404,
message: error.message
};
break;
default:
errorObj = {
status: error.response.status,
message: error.response.data
};
break;
}
} else {
errorObj = { message: error.message };
}
updateItemList({ "error": errorObj, type: "updateError" });
}
}
fetchApi();    
},[]);
return [
itemList.isLoading,
itemList.data,
itemList.error
];
}

不幸的是,react提示以下消息:

React Hook "useAxios"不能在类组件中调用。React Hooks必须在React函数组件或自定义React Hook函数中调用。

那么,将所有相关的钩子组合在一起的最佳实践是什么呢?

使用静态类方法作为钩子在运行时可以工作,但是linter假定你在类组件中使用钩子(尽管它不是),这是钩子规则所禁止的。

一个简单的解决方法是将它们定义为单独的函数,然后将它们导出到单个对象下:

function useListProduct() {
let url="list product API URL";
return useAxios(null,"get",url);
}
function useAddProduct(product) {
let url="list product API URL";
return useAxios(product,"post",url);
}
export const Product = {
useListProduct,
useAddProduct,
}

或者将每个函数导出为命名函数,然后在导入或重新导出时捆绑它们:

export function useListProduct() {
let url="list product API URL";
return useAxios(null,"get",url);
}

export function useAddProduct(product) {
let url="list product API URL";
return useAxios(product,"post",url);
}

然后在另一个文件中:

import * as Product from './product';

export * as Product from './product';

相关内容

最新更新