Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@umijs/use-request
Advanced tools
Production-ready React Hooks library for manage asynchronous data.
$ npm i @umijs/use-request --save
# or
$ yarn add @umijs/use-request
//service 为异步函数。
const {data, error, loading} = useRequest(service);
import React from 'react';
import useRequest from '@umijs/use-request';
export default () => {
const { data, error, loading } = useRequest(getUserInfo)
if (error) return <div>failed to load</div>
if (loading) return <div>loading...</div>
return <div>hello {data.username}!</div>
}
在这个例子中, useRequest 接收了一个异步函数 getUserInfo
,在组件初次加载时,自动触发该函数执行。同时 useRequest 会自动管理异步请求的 loading
, data
, error
等状态。
如 快速开始 例子一样, useRequest 在组件初始化时会默认执行 service。
通过设置 options.manual = true
, 则需要手动调用 run
时才会触发执行。
const { loading, run } = useRequest(changeUsername, {
manual: true,
});
<button onClick={() => run('new name')}>
{loading ? 'Editting...' : 'Edit'}
</button>
你可以通过 mutate
,直接修改 data
。 mutate
函数参数可以为 newData
或 (data)=> newData
。
const { data, mutate } = useRequest(getUserInfo);
<button onClick={() => mutate('new name')}>
Edit
</button>
通过设置 pollingInterval
,进入轮询模式,定时触发函数执行。同时可以通过设置 pollingWhenHidden = false
,在屏幕不可见时,暂时暂停定时任务。
run
/ cancel
来 开启/停止 轮询。manual=true
时,需要第一次执行 run
后,才开始轮询。const { data, loading } = useRequest(getUserInfo, {
pollingInterval: 1000,
pollingWhenHidden: false
});
通过设置 debounceInterval
,则进入防抖模式。此时如果频繁触发 run
,则会以防抖策略进行请求。
const { data, loading, run } = useRequest(getUserInfo, {
debounceInterval: 500
});
通过设置 throttleInterval
,则进入节流模式。此时如果频繁触发 run
,则会以节流策略进行请求。
const { data, loading, run } = useRequest(getUserInfo, {
throttleInterval: 500
});
如果设置了 cacheKey
, useRequest 会将当前请求结束数据缓存起来。下次组件初始化时,如果有缓存数据,我们会优先返回缓存数据,然后在背后发送新请求,也就是 SWR 的能力。
const { data, loading, run } = useRequest(getInfo, {
cachekey: 'getInfoKey'
});
同一个 cacheKey
的请求,是全局共享的,也就是你可以提前加载数据。利用该特性,可以很方便的实现预加载。你可以在线上例子中体验一下。
如果你设置了 refreshOnWindowFocus = true
,则在浏览器窗口 refouc
和 revisible
时,会重新发起请求。
你可以通过设置 focusTimespan
来设置请求间隔,默认为 5000ms
。
const { data, loading } = useRequest(getUserInfo, {
refreshOnWindowFocus: true,
focusTimespan: 5000
});
通过 fetchKey
,可以将请求进行分类,每一类的请求都有独立的状态,你可以在 fetches
中找到所有的请求。
const { run, fetches } = useRequest(disableUser, {
manual: true,
fetchKey: (id) => id,
});
通过设置 loadingDelay
,可以延迟 loading
变成 true
的时间,有效防止请求抖动。
const withLoadingDelayAction = useRequest(getCurrentTime, {
loadingDelay: 200
});
当某些 state
变化时,我们需要重新执行异步请求,一般我们会这样写代码:
const [userId, setUserId] = useState('1');
const { data, run, loading } = useRequest(getUserSchool, { manual: true });
useEffect(() => {
run();
}, [userId]);
refreshDeps
是一个语法糖,让你更方便的实现上面的功能。当 refreshDeps
变化时,我们会重新执行异步请求。
const [userId, setUserId] = useState('1');
const { data, run, loading } = useRequest(() => {
return getUserSchool()
}, {
refreshDeps: [userId]
});
const {
data,
error,
loading,
run,
params,
cancel,
refresh,
mutate,
fetches,
} = useRequest(service, {
manual,
initialData,
refreshDeps,
onSuccess,
onError,
formatResult,
cacheKey,
loadingDelay,
defaultParams,
pollingInterval,
pollingWhenHidden,
fetchKey,
refreshOnWindowFocus,
focusTimespan,
debounceInterval,
throttleInterval,
});
data: undefined | any
service 返回的数据,默认为 undefined
。
formatResult
, 则该数据为被格式化后的数据。error: undefined | Error
undefined
。loading: boolean
run: (...args: any[]) => Promise
params: any[]
run(1, 2, 3)
,则 params 等于 [1, 2, 3]
cancel: () => void
refresh: () => void
mutate: data | (data)=>newData
fetches: {[key:string]: {loading,data,error,params,cancel,refresh,mutate,run}}
fetchKey
,则可以实现多个请求并行,fetches
存储了多个请求的状态。所有的 Options 均是可选的。
manual: boolean
false
。 即在初始化时自动执行 service。true
,则需要手动调用 run
触发执行。initialData: any
refreshDeps: any[]
manual = false
时,refreshDeps
变化,会触发 service 重新执行。formatResult: (response: any) => any
onSuccess: (data:any, params: any[]) => void
data
和 params
formmatResult
,则 data
为格式化后数据。onError: (error: Error, params: any[]) => void
error
和 params
。fetchKey: (...params: any[]) => string
fetches
中同时维护不同 key
值的请求状态。cacheKey: string
cacheKey
,我们会启用缓存机制。data
, error
, params
, loading
。defaultParams: any[]
manual=false
,自动执行 run
的时候,默认带上的参数。loadingDelay: number
pollingInterval: number
run
。pollingWhenHidden: boolean
true
,即不会停止轮询。false
, 在页面隐藏时会暂时停止轮询,页面重新显示时继续上次轮询。refreshOnWindowFocus: boolean
false
,即不会重新发起请求。true
,在屏幕重新聚焦或重新显示时,会重新发起请求。focusTimespan: number
5000ms
refreshOnWindowFocus
使用。debounceInterval: number
throttleInterval:number
基于基础的 useRequest,我们可以进一步封装,实现更高级的定制需求。当前 useRequest 内置了 集成请求库
,分页
和 加载更多
三种场景。你可以参考代码,实现自己的封装。参考 useRequest、usePaginated、useLoadMore 的实现。
如果 service 是 string
、 object
、 (...args)=> string|object
, 我们会自动使用 um-request 来发送网络请求。umi-request 是类似 axios、fetch 的请求库。
// 用法 1
const { data, error, loading } = useRequest('/api/userInfo');
// 用法 2
const { data, error, loading } = useRequest({
url: '/api/changeUsername',
method: 'post',
});
// 用法 3
const { data, error, loading } = useRequest((userId)=> `/api/userInfo/${userId}`);
// 用法4
const { loading, run } = useRequest((username) => ({
url: '/api/changeUsername',
method: 'post',
data: { username },
}), {
manual: true,
});
Q:如果我要使用 axios
、fetch
咋办?如何设置 umi-request
的全局配置?
A:你可以通过设置 requestMehod
即可。参考 示例代码。当然,你可以通过 UseAPIProvider 全局设置请求方法哦。
const {...} = useRequest<R>(
service: string | object | ((...args:any) => string | object),
{
...,
requestMehod?: (service) => Promise
})
如果 service 是 string
、 object
、 (...args)=> string|object
,则自动使用 umi-request
来发送请求。
requestMehod:(service: string|object)) => Promise
通过设置 options.paginated = true
, useRequest 将以分页模式运行,此时会有以下特性:
current
, pageSize
。service 的第一个参数为 {current, pageSize}
。{list: Item[], total: number}
,如果不满足,可以通过 options.formatResult
转换一次。pagination
字段,包含所有分页信息,及操作分页的函数。refreshDeps
变化,会重置 current
到第一页,并重新发起请求,一般你可以把 pagination 依赖的条件放这里。普通的分页场景,我们会自动管理 current
和 pageSize
const { data, loading, pagination } = useRequest(
({ current, pageSize }) => getUserList({ current, pageSize }),
{
paginated: true,
}
);
由于 antd Table 使用比较广泛,我们特别支持了 antd Table 需要的分页格式,及 sorter
、 filters
等。你可以通过 result.tableProps
, result.filters
, result.sorter
访问到这些属性。
const { tableProps, sorter, filters } = useRequest((params) => {
return getUserList(params);
}, {
paginated: true
});
return (<Table columns={columns} rowKey="id" {...tableProps} />);
在 cacheKey
场景下, run
的参数 params
是可以缓存的,利用这个特点,我们可以实现 pagination 相关条件的缓存。
一个复杂的带条件,带缓存的 pagination 例子。
const {
...,
pagination: {
current: number;
pageSize: number;
total: number;
totalPage: number;
onChange: (current: number, pageSize: number) => void;
changeCurrent: (current: number) => void;
changePageSize: (pageSize: number) => void;
};
tableProps: {
dataSource: Item[];
loading: boolean;
onChange: (
pagination: PaginationConfig,
filters?: Record<keyof Item, string[]>,
sorter?: SorterResult<Item>,
) => void;
pagination: {
current: number;
pageSize: number;
total: number;
};
};
sorter?: SorterResult<Item>;
filters?: Record<keyof Item, string[]>;
} = useRequest(service, {
...,
paginated,
defaultPageSize,
refreshDeps,
});
pagination
tableProps
sorter
filters
paginated: boolean
false
。true
,则开启分页模式。在分页模式下,service 的第一个参数为 {curret, pageSize, sorter, filters}
。formatResult
结果必须为 {list: Item[], total: number}
。refreshDeps
refreshDeps
变化,会重置 current
到第一页,并重新发起请求,一般你可以把依赖的条件放这里。通过设置 options.loadMore = true
, useRequest 将以 loadMore 模式运行,此时会有以下特性:
{list: Item[], nextId: string|undefined}
,如果不满足,可以通过 options.formatResult
转换一次。nextId
。result.loadingMore
和 result.loadMore
。refreshDeps
变化,会清空当前数据,并重新发起请求,一般你可以把 loadMore 依赖的条件放这里。const { data, run, loadMore, loading, loadingMore } = useRequest((nextId) => {
return getUserList(nextId);
}, {
loadMore: true
});
const {
...,
loadMore,
loadingMore,
} = useRequest(service, {
...,
loadMore,
refreshDeps,
});
loadMore: ()=>void
loadingMore: boolean
loadMore: boolean
false
。true
,则开启加载更多模式。在该模式下,service 的第一个参数为 nextId
。formatResult
结果必须为 {list: Item[], nextId: string|undefined}
。refreshDeps
refreshDeps
变化,会清空当前数据,并重新发起请求,一般你可以把依赖的条件放这里。你可以通过 UseAPIProvider
在项目的最外层设置全局 options。
import {UseAPIProvider} from '@umijs/use-request';
export function ({children})=>{
return (
<UseAPIProvider value={{
refreshOnWindowFocus: true,
requestMethod: (param)=> axios(param),
...
}}>
{children}
</UseAPIProvider>
)
}
FAQs
React Hooks for fetching, caching and updating asynchronous data
The npm package @umijs/use-request receives a total of 3,845 weekly downloads. As such, @umijs/use-request popularity was classified as popular.
We found that @umijs/use-request demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 14 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.