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

tktrz96b  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(159)

有可能对钩子进行群体React吗?
我有几个相关的自定义钩子,例如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挂接“useAxios”。必须在React函数组件或自定义React挂接函数react-hooks/rules-of-hooks中调用React挂接
那么,将所有相关的钩子组合在一起的最佳实践是什么呢?

cyej8jka

cyej8jka1#

使用静态类方法作为钩子在运行时可以工作,但是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';

相关问题