创建自定义钩子时反应TypeError

时间:2020-02-25 18:50:49

标签: reactjs

我有以下钩子

import axios from "axios";
import {useKeycloak} from "@react-keycloak/web";
import {useEffect, useState} from "react";

export const useAdminApi = () => {

    const {keycloak} = useKeycloak();
    const [axiosInstance, setAxiosInstance] = useState(undefined);

    useEffect(() => {
        let instance = axios.create({
            baseURL: `${process.env.REACT_APP_ADMIN_API_URL}`,
            headers: {
                Test: 'test',
                Authorization: 'Bearer ' + keycloak.token,
            }
        });

        setAxiosInstance(instance);

        return () => {
            setAxiosInstance(undefined);
        }
    }, [keycloak.token]);

    const getUsers = ({query}) => {
        return axiosInstance.get(`/users${query}`)
    };

    const getUserDetail = ({userId}) => {
        return axiosInstance.get(`/users/${userId}`)
    };

    const deleteUser = ({userId}) => {
        return axiosInstance.delete(`/users/${userId}`)
    };


    return {
        getUsers,
        getUserDetail,
        deleteUser
    }
};

当我登录instance时,它会记录所有配置

我想从useAdminApi中导出诸如getUserDetaildeleteUser,...之类的函数。

然后在其他组件中,我想使用此功能,因此需要满足以下条件:

const UserForm = () => {
    const {getUserDetail} = useAdminApi();

    useEffect(() => {
        if (!userId) {
            setIsNew(true);
        } else {
            setIsNew(false);
            getUserDetail({userId})
                .then(result => setUserData(result.data))
                .catch(error => pushError(push, error));
        }
    }, [userId]);

   ...
}

但是,当我显示UserForm时,出现以下错误:TypeError: Cannot read property 'get' of undefined指向此行return axiosInstance.get(`/users/${userId}`)

有人可以告诉我这种方法有什么问题吗?

1 个答案:

答案 0 :(得分:1)

您正在将axiosInstance的初始值设置为undefined,但是TypeScript不会推断您想要的类型。 useState是一个泛型函数,因此您可以自己传递类型。

import axios, { AxiosInstance } from 'axios';
const [axiosInstance, setAxiosInstance] = useState<AxiosInstance | undefined>(
  undefined
);

然后在您的函数中,您仍然需要检查axiosInstance是否为undefined

如果您拥有TypeScript 3.7或更高版本,则可以使用“可选链接”来实现。

const getUsers = ({ query }: any) => {
  return axiosInstance?.get(`/users${query}`);
};