为了账号安全,请及时绑定邮箱和手机立即绑定

useRequest学习:新手入门教程

概述

useRequest 是一个用于在 React 应用程序中进行 HTTP 请求的 Hook,结合了 useEffectuseState 的功能,使得请求逻辑和状态管理更加简洁直观。useRequest 通常用于从远程服务器获取数据或向服务器发送数据,实现数据的同步更新。本文将详细介绍 useRequest 的用法、配置选项和常见应用场景。

什么是useRequest

useRequest 是一个用于在 React 应用程序中进行 HTTP 请求的 Hook。它通过将请求逻辑和状态管理集成到组件中,简化了数据的获取和更新流程。与传统的请求方式相比,useRequest 具有以下优势:

  • 代码简洁:请求逻辑直接嵌入到组件中,减少了复杂的状态管理和副作用处理。
  • 响应式更新:当请求的数据发生变化时,组件能够自动更新显示的新数据。
  • 错误处理:方便地捕获和处理请求中的错误。

useRequest 的常见应用场景包括:

  • 获取用户信息、产品列表等数据。
  • 发布评论、点赞等用户行为。
  • 刷新页面中的某些数据。
useRequest的基本用法

使用 useRequest 的基本步骤包括:

  1. 引入库:首先需要引入 useRequest 和相关的库,通常会使用 axios 作为 HTTP 客户端。
  2. 定义请求配置:定义请求的 URL、方法、参数等。
  3. 使用 Hook:利用 useRequest Hook 进行请求。
  4. 处理响应:在请求成功时更新组件状态或执行其他操作。

示例代码

import React, { useState } from 'react';
import axios from 'axios';
import { useRequest } from 'ahooks'; // 引入 ahooks 库中的 useRequest

const MyComponent = () => {
    const [data, setData] = useState(null);

    const { run, loading, error } = useRequest(
        () => axios.get('https://api.example.com/data'), // 定义请求配置
        {
            onSuccess: (data) => { // 请求成功时的回调
                console.log(data);
                setData(data);
            },
            onError: (error) => { // 请求出错时的回调
                console.error(error);
            },
            manual: true // 手动触发请求,默认是 false
        }
    );

    return (
        <div>
            {loading && <div>Loading...</div>}
            {error && <div>Error!</div>}
            {data && <div>Data: {JSON.stringify(data)}</div>}
            <button onClick={run}>Fetch Data</button> // 手动触发请求
        </div>
    );
};

export default MyComponent;
``

### 代码解析

- `useRequest` 接收两个参数,第一个是请求函数,第二个是配置对象。
- `run` 是一个触发请求的函数。
- `loading` 是一个布尔值,表明请求是否正在进行。
- `error` 是一个错误对象,表示请求过程中发生错误。
- `onSuccess` 和 `onError` 分别是请求成功和失败时的回调函数。

## useRequest的配置选项详解

`useRequest` Hook 接收一个配置选项作为第二个参数,这些配置选项可以自定义 Hook 的行为。以下是一些常见的配置选项:

### `manual`

默认值:`false`
- **描述**:如果为 `true`,则请求不会在组件挂载时自动触发,需要手动调用 `run` 函数来触发请求。
- **示例**:
    ```jsx
    const { run, loading, data } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            manual: true
        }
    );

onSuccess

  • 描述:请求成功时执行的回调函数。
  • 示例
    const { run, loading, data } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onSuccess: (data) => {
                console.log('Success:', data);
            }
        }
    );

onError

  • 描述:请求失败时执行的回调函数。
  • 示例
    const { run, loading, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

onSettled

  • 描述:无论请求成功还是失败都会执行的回调函数。
  • 示例
    const { run, loading, data, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onSettled: (data, error) => {
                console.log('Settled:', data, error);
            }
        }
    );

onMount

  • 描述:在组件挂载时自动触发请求。
  • 示例
    const { loading, data, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onMount: true
        }
    );

onUpdate

  • 描述:在请求更新时执行的回调函数。
  • 示例
    const { update, loading, data } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onUpdate: (data) => {
                console.log('Update:', data);
            }
        }
    );

dependencies

  • 描述:请求配置的依赖列表。当这些依赖发生变化时,会重新发起请求。
  • 示例
    const { run, loading, data, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            dependencies: ['someKey'],
            onSuccess: (data) => {
                console.log('Success:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

onAbort

  • 描述:请求被取消时执行的回调函数。
  • 示例
    const { abort, loading, data, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onAbort: (data) => {
                console.log('Abort:', data);
            }
        }
    );

onTrigger

  • 描述:在请求触发时执行的回调函数。
  • 示例
    const { run, loading, data, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onTrigger: (data) => {
                console.log('Trigger:', data);
            }
        }
    );
useRequest的常见应用场景

useRequest 可以用于各种需要与服务器交互的场景,以下是一些常见的应用场景:

获取初始数据

在组件挂载时从服务器获取初始数据:

const MyComponent = () => {
    const { data, loading, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onMount: true,
            onSuccess: (data) => {
                console.log('Initial data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return <div>Data: {JSON.stringify(data)}</div>;
};

手动触发请求

当用户点击按钮时手动触发请求:

const MyComponent = () => {
    const [trigger, { data, loading, error }] = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            manual: true,
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error).
            { console.error('Error:', error); }
        }
    );
    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return (
        <div>
            <button onClick={trigger}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

更新数据

依赖于某些变化重新发起请求:

const MyComponent = () => {
    const [key, setKey] = useState('initialKey');
    const { data, loading, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        { dependencies: [key],
            onSuccess: (data) => {
            console.log('Data:', data);
        },
        onError: (error) => {
            console.error('Error:', error);
        }
    });

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return (
        <div>
            <div>Data: {JSON.stringify(data)}</div>
            <button onClick={() => setKey('newKey')}>Update Key</button>
        </div>
    );
};

请求取消

在组件卸载时取消请求,避免不必要的请求:

const MyComponent = () => {
    const { run, loading, data, error, abort } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onMount: true,
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            onUnmount: () => {
                abort();
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return (
        <div>
            <div>Data: {JSON.stringify(data)}</div>
        </div>
    );
};

请求重试

请求失败时自动重试:

const MyComponent = () => {
    const { run, loading, data, error, retry } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onMount: true,
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
                retry();
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};
useRequest的错误处理方法

useRequest 提供了多种方式处理请求中的错误情况,以下是一些常见的错误处理方法:

基本错误处理

在请求失败时执行错误处理逻辑:

const MyComponent = () => {
    const { run, loading, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error!</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
        </div>
    );
};

自定义错误处理

使用自定义的错误处理函数,例如显示错误消息:

const MyComponent = () => {
    const [errorMessage, setErrorMessage] = useState(null);

    const { run, loading, error } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onError: (error) => {
                console.error('Error:', error);
                setErrorMessage(error.message);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {errorMessage}</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
        </div>
    );
};

自动重试

请求失败时自动重试,直到请求成功或达到最大重试次数:

const MyComponent = () => {
    const { run, loading, data, error, retry } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onError: (error) => {
                console.error('Error:', error);
                retry();
            },
            retry: { times: 3, interval: 1000 }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

请求取消

在某些情况下取消请求,例如页面卸载时:

const MyComponent = () => {
    const { run, loading, data, error, abort } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onMount: true,
            onError: (error) => {
                console.error('Error:', error);
            },
            onUnmount: () => {
                abort();
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <div>Data: {JSON.stringify(data)}</div>
        </div>
    );
};
useRequest的优化技巧

使用缓存

减少不必要的请求,提高应用性能:

const MyComponent = () => {
    const { run, loading, data, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            cache: true
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

调整请求间隔

控制请求的时间间隔,避免过度请求:

const MyComponent = () => {
    const { run, loading, data, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            interval: 3000
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

使用错误码处理

根据不同的错误码返回不同的处理逻辑:

const MyComponent = () => {
    const [error, setError] = useState(null);

    const { run, loading, data, error: requestError } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
                setError(error);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) {
        if (error.response && error.response.status === 401) {
            return <div>Unauthorized</div>;
        }
        if (error.response && error.response.status === 404) {
            return <div>Not Found</div>;
        }
        return <div>Error: {error.message}</div>;
    }

    return (
        <div>
            <button onClick={run}>Fetch Data</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

使用依赖关系

根据依赖关系重新发起请求,避免不必要的请求:

const MyComponent = () => {
    const [key, setKey] = useState('initialKey');
    const { data, loading, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            dependencies: [key],
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={() => setKey('newKey')}>Update Key</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

并发请求

同时发起多个请求,并对每个请求的结果进行处理:

const MyComponent = () => {
    const [data1, setData1] = useState(null);
    const [data2, setData2] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const request1 = useRequest(
        () => axios.get('https://api.example.com/data1'),
        {
            onSuccess: (data) => {
                console.log('Data1:', data);
                setData1(data);
            },
            onError: (error) => {
                console.error('Error1:', error);
                setError(error);
            }
        }
    );

    const request2 = useRequest(
        () => axios.get('https://api.example.com/data2'),
        {
            onSuccess: (data) => {
                console.log('Data2:', data);
                setData2(data);
            },
            onError: (error) => {
                console.error('Error2:', error);
                setError(error);
            }
        }
    );

    React.useEffect(() => {
        setLoading(true);
        request1.run();
        request2.run();
    }, []);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <div>Data1: {JSON.stringify(data1)}</div>
            <div>Data2: {JSON.stringify(data2)}</div>
        </div>
    );
};

数据缓存和版本控制

使用缓存来减少请求次数,并在必要时更新缓存数据:

const MyComponent = () => {
    const [key, setKey] = useState('initialKey');
    const { data, loading, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            dependencies: [key],
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            cache: true
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={() => setKey('newKey')}>Update Key</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

优化请求参数

根据不同的场景动态调整请求参数:

const MyComponent = () => {
    const [params, setParams] = useState({ key: 'initialKey' });
    const { data, loading, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            dependencies: [params],
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <button onClick={() => setParams({ key: 'newKey' })}>Update Params</button>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

使用中间件

使用中间件来处理请求前后的逻辑:

const MyComponent = () => {
    const { data, loading, error } = useRequest(
        (params) => axios.get('https://api.example.com/data', { params }),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
            },
            onError: (error) => {
                console.error('Error:', error);
            },
            onBeforeRequest: ({ params }) => {
                console.log('Before request:', params);
                return params;
            },
            onAfterRequest: (data) => {
                console.log('After request:', data);
                return data;
            }
        }
    );

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            {data && <div>Data: {JSON.stringify(data)}</div>}
        </div>
    );
};

持久化状态

在组件卸载后再重新加载时保留请求状态:

const MyComponent = () => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const { run, loading: requestLoading, error: requestError } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
                setData(data);
            },
            onError: (error) => {
                console.error('Error:', error);
                setError(error);
            }
        }
    );

    React.useEffect(() => {
        setLoading(true);
        run();
    }, []);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <div>Data: {JSON.stringify(data)}</div>
        </div>
    );
};

使用上下文

在组件树中共享请求状态和逻辑:

import React, { useContext, useState } from 'react';
import axios from 'axios';
import { useRequest } from 'ahooks';
import { RequestContext } from './RequestContext';

const MyComponent = () => {
    const { data, loading, error } = useContext(RequestContext);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;

    return (
        <div>
            <div>Data: {JSON.stringify(data)}</div>
        </div>
    );
};

const RequestProvider = ({ children }) => {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

    const { run, loading: requestLoading, error: requestError } = useRequest(
        () => axios.get('https://api.example.com/data'),
        {
            onSuccess: (data) => {
                console.log('Data:', data);
                setData(data);
            },
            onError: (error) => {
                console.error('Error:', error);
                setError(error);
            }
        }
    );

    React.useEffect(() => {
        setLoading(true);
        run();
    }, []);

    return (
        <RequestContext.Provider value={{ data, loading, error }}>
            {children}
        </RequestContext.Provider>
    );
};

export default RequestProvider;

总结,useRequest 是一个强大且灵活的 Hook,可以用于各种复杂的 HTTP 请求场景。通过合理配置和使用,可以有效提升应用的性能和用户体验。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消