Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用带参数的API钩子_Reactjs_Api_React Hooks - Fatal编程技术网

Reactjs 使用带参数的API钩子

Reactjs 使用带参数的API钩子,reactjs,api,react-hooks,Reactjs,Api,React Hooks,我正在尝试使用中的第一个答案中描述的hook useAPI 但我有一个主要问题。在我的组件中,当url本身中有可能还没有值的参数时,我呈现useAPI,这会导致错误。这些值来自不同的API调用。在定义参数时,如何仅使用参数呈现useAPI钩子 我的代码如下所示: const Availability = () => { [account, setAccount] = useState(0); const savedApiData = useAPI({

我正在尝试使用中的第一个答案中描述的hook useAPI 但我有一个主要问题。在我的组件中,当url本身中有可能还没有值的参数时,我呈现useAPI,这会导致错误。这些值来自不同的API调用。在定义参数时,如何仅使用参数呈现useAPI钩子

我的代码如下所示:

const Availability = () => {
     [account, setAccount] = useState(0);
     const savedApiData = useAPI({
         endpoint:'/programs/${state.account.id}/', // The account obj comes from a different useAPI in this component
         requestType: 'POST',
         body: {
            siteIds: !state.siteId ? [] : [state.siteId] 
         }
     }); 
}

在第一次呈现时,API url将出现一个错误,显示“无法读取未定义的属性”id“。

这非常简单,在第四行中,您正在访问
state.account
id
属性,但是
account
此处未定义(可能是因为它不存在)。为了解决这个问题,您可以在
state.account
未定义时使用一个虚拟id(但您最终肯定会从服务器获得一个404,因此您必须处理这个问题),或者根本不使用
useApi
。钩子真的很难修补,有时钩子的一个未处理的小用例会使它完全无用

另一个想法是允许
endpoint
hook config参数作为函数(仅在请求时调用),并向该对象添加另一个布尔参数,以控制是否应执行请求

然后,如果
state.account
未定义,则不会执行任何请求,
endpoint
函数永远不会执行,也不会发生错误,并且当
state.account
具有值时,钩子可以重新尝试启动请求,调用
endpoint
函数,这次不会出现错误

示例(未测试):

const useApi = ({endpoint, requestType, body, doRequest = true}) => {
    const [data, setData] = useState({ fetchedData: [], isError: false, isFetchingData: false });
    useEffect(() => {
        if (doRequest) requestApi();
    }, [endpoint, doRequest]); // Retry request when doRequest's value changes
    const requestApi = async () => {
        // invoke endpoint if it is a function
        let endpointUrl = typeof endpoint === 'function' ? endpoint() : endpoint;
        let response = {};
        try {
            setData({ ...data, isFetchingData: true });
            console.log(endpointUrl);
            switch (requestType) {
                case 'GET':
                    return (response = await axios.get(endpointUrl));
                case 'POST':
                    return (response = await axios.post(endpointUrl, body));
                case 'DELETE':
                    return (response = await axios.delete(endpointUrl));
                case 'UPDATE':
                    return (response = await axios.put(endpointUrl, body));
                case 'PATCH':
                    return (response = await axios.patch(endpointUrl, body));
                default:
                    return (response = await axios.get(endpoint));
            }
        } catch (e) {
            console.error(e);
            setData({ ...data, isError: true });
        } finally {
            if (response.data) {
                setData({ ...data, isFetchingData: false, fetchedData: response.data.mainData });

            }
        }
    };
    return data;
};
用法:

const Availability = () => {
     [account, setAccount] = useState(0);
     const savedApiData = useAPI({
         endpoint: () => '/programs/${state.account.id}/', // Replace string literal with a factory function
         requestType: 'POST',
         body: {
            siteIds: !state.siteId ? [] : [state.siteId] 
         },
         doRequest: !!state.account, // Only request if account exists
     }); 
}

这非常简单,在第四行中,您正在访问
state.account
id
属性,但是这里的
account
没有定义(可能是因为它不存在)。为了解决这个问题,您可以在
state.account
未定义时使用一个虚拟id(但您最终肯定会从服务器获得一个404,因此您必须处理这个问题),或者根本不使用
useApi
。钩子真的很难修补,有时钩子的一个未处理的小用例会使它完全无用

另一个想法是允许
endpoint
hook config参数作为函数(仅在请求时调用),并向该对象添加另一个布尔参数,以控制是否应执行请求

然后,如果
state.account
未定义,则不会执行任何请求,
endpoint
函数永远不会执行,也不会发生错误,并且当
state.account
具有值时,钩子可以重新尝试启动请求,调用
endpoint
函数,这次不会出现错误

示例(未测试):

const useApi = ({endpoint, requestType, body, doRequest = true}) => {
    const [data, setData] = useState({ fetchedData: [], isError: false, isFetchingData: false });
    useEffect(() => {
        if (doRequest) requestApi();
    }, [endpoint, doRequest]); // Retry request when doRequest's value changes
    const requestApi = async () => {
        // invoke endpoint if it is a function
        let endpointUrl = typeof endpoint === 'function' ? endpoint() : endpoint;
        let response = {};
        try {
            setData({ ...data, isFetchingData: true });
            console.log(endpointUrl);
            switch (requestType) {
                case 'GET':
                    return (response = await axios.get(endpointUrl));
                case 'POST':
                    return (response = await axios.post(endpointUrl, body));
                case 'DELETE':
                    return (response = await axios.delete(endpointUrl));
                case 'UPDATE':
                    return (response = await axios.put(endpointUrl, body));
                case 'PATCH':
                    return (response = await axios.patch(endpointUrl, body));
                default:
                    return (response = await axios.get(endpoint));
            }
        } catch (e) {
            console.error(e);
            setData({ ...data, isError: true });
        } finally {
            if (response.data) {
                setData({ ...data, isFetchingData: false, fetchedData: response.data.mainData });

            }
        }
    };
    return data;
};
用法:

const Availability = () => {
     [account, setAccount] = useState(0);
     const savedApiData = useAPI({
         endpoint: () => '/programs/${state.account.id}/', // Replace string literal with a factory function
         requestType: 'POST',
         body: {
            siteIds: !state.siteId ? [] : [state.siteId] 
         },
         doRequest: !!state.account, // Only request if account exists
     }); 
}

谢谢你的回答!我不太明白你关于端点回调的第二个建议,你能用一个基本的代码示例详细说明一下吗?我刚刚添加了一个示例谢谢你的回答!我不太明白你关于端点回调的第二个建议,你能用一个基本的代码示例详细说明一下吗?我只是添加了一个示例