语法
一、自动请求
1. 基础自动请求
import { useRequest } from "ahooks";
function App() {
const queryData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("哈哈");
}, 3000);
});
};
const { data, loading } = useRequest(queryData);
return <div>{loading ? "正在请求中" : data}</div>;
}
export default App;
2. 携带默认参数自动请求
如果我们设置了 options.manual = false
, 则首次调用 service
的参数可以通过 options.defaultParams
来设置。
import { useRequest } from "ahooks";
function App() {
const queryData = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(params);
}, 3000);
});
};
const { data, loading } = useRequest(queryData,{
defaultParams: ["哈哈"]
});
return <div>{loading ? "正在请求中" : data}</div>;
}
export default App;
二、手动请求
如果设置了 options.manual = true
, 则 useRequest
不会默认执行, 需要通过 run
或者 runAsync
来触发执行。
run
与 runAsync
的区别在于:
-
run 是一个普通的同步函数,我们会自动捕获异常,你可以通过 options.onError 来处理异常时的行为
-
runAsync 是一个返回 Promise 的异步函数,如果使用 runAsync 来调用,则意味着你需要自己捕获异常
1. 基础手动请求
import { useRequest } from "ahooks";
function App() {
const queryData = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(params);
}, 3000);
});
};
const { data, loading, run, runAsync } = useRequest(queryData, {
manual: true,
});
return (
<div>
<div>
<button onClick={() => run("哈哈")}>run</button>
<button onClick={() => runAsync("嘻嘻")}>runAsync</button>
</div>
{loading ? "正在请求中" : data}
</div>
);
}
export default App;
2. 携带生命周期手动请求
useRequest 提供了以下几个生命周期配置项,供你在异步函数的不同阶段做一些处理。
- onBefore: 请求之前触发
- onSuccess: 请求成功触发
- onError: 请求失败触发
- onFinally: 请求完成触发
import { useRequest } from "ahooks";
function App() {
const queryData = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(params);
// reject(params);
}, 3000);
});
};
const { data, loading, run, runAsync } = useRequest(queryData, {
manual: true,
onBefore(params) {
console.log("onBefore 阶段", params);
},
onSuccess(value) {
console.log("onSuccess 阶段", value);
},
onError(error) {
console.log("onError 阶段", error);
},
onFinally(params, value, error) {
console.log("onFinally 阶段", params, value, error);
},
});
return (
<div>
<div>
<button onClick={() => run("哈哈")}>run</button>
<button onClick={() => runAsync("嘻嘻")}>runAsync</button>
</div>
{loading ? "正在请求中" : data}
</div>
);
}
export default App;
3. 重复上一次手动请求
useRequest 提供了 refresh
和 refreshAsync
方法,使我们可以使用上一次的参数,重新发起请求。
import { useRequest } from "ahooks";
function App() {
const queryData = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(params);
// reject(params);
}, 3000);
});
};
const { data, loading, run, runAsync, refresh, refreshAsync } = useRequest(
queryData,
{
manual: true,
onBefore(params) {
console.log("onBefore 阶段", params);
},
onSuccess(value) {
console.log("onSuccess 阶段", value);
},
onError(error) {
console.log("onError 阶段", error);
},
onFinally(params, value, error) {
console.log("onFinally 阶段", params, value, error);
},
}
);
return (
<div>
<div>
<button onClick={() => run("哈哈")}>run</button>
<button onClick={() => runAsync("嘻嘻")}>runAsync</button>
<button onClick={refresh}>refresh</button>
<button onClick={refreshAsync}>refreshAsync</button>
</div>
{loading ? "正在请求中" : data}
</div>
);
}
export default App;
4. 立即变更数据
useRequest 提供了 mutate
, 支持立即修改 useRequest
返回的 data
参数。mutate
的用法与 React.setState
一致,支持 mutate(newData)
和 mutate((oldData) => newData)
两种写法。
import { useRequest } from "ahooks";
function App() {
const queryData = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(params);
// reject(params);
}, 3000);
});
};
const { data, run, runAsync, refresh, refreshAsync, mutate } =
useRequest(queryData, {
manual: true,
onBefore(params) {
console.log("onBefore 阶段", params);
},
onSuccess(value) {
console.log("onSuccess 阶段", value);
},
onError(error) {
console.log("onError 阶段", error);
},
onFinally(params, value, error) {
console.log("onFinally 阶段", params, value, error);
},
});
return (
<div>
<div>
<button
onClick={() => {
mutate("哈哈");
run("哈哈");
}}
>
run
</button>
<button onClick={() => runAsync("嘻嘻")}>runAsync</button>
<button onClick={refresh}>refresh</button>
<button onClick={refreshAsync}>refreshAsync</button>
</div>
{data}
</div>
);
}
export default App;
三、轮询
通过设置 options.pollingInterval
, 进入轮询模式。useRequest
会定时触发 service
执行。
基础轮询
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 4000);
});
};
const { data, loading, error, run, runAsync } = useRequest(getName, {
manual: true,
pollingInterval: 1000,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("哈哈")}>run</button>
{render()}
</div>
);
}
export default App;
后台轮询
通过设置 options.pollingWhenHidden
, 进入后台轮询。在页面隐藏时,是否继续轮询。如果设置为 false
, 在页面隐藏时会暂时停止轮询,页面重新显示时继续上次轮询。
import React from "react";
import { useRequest } from "./ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 4000);
});
};
const { data, loading, error, run, runAsync } = useRequest(getName, {
manual: true,
pollingInterval: 1000,
pollingWhenHidden: true,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("哈哈")}>run</button>
{render()}
</div>
);
}
export default App;
轮询错误重试
通过设置 options.pollingErrorRetryCount
, 进入轮询模式
四、防抖
通过设置 options.debounceWait
, 进入防抖模式,此时如果频繁触发 run
或者 runAsync
,则会以防抖策略进行请求。
延迟结束后执行
import React from "react";
import { useRequest } from "./ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error, run } = useRequest(getName, {
manual: true,
debounceWait: 5000,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("嘻嘻")}>run</button>
{render()}
</div>
);
}
export default App;
延迟开始前执行
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error, run } = useRequest(getName, {
manual: true,
debounceWait: 5000,
debounceLeading: true,
debounceTrailing: false
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("嘻嘻")}>run</button>
{render()}
</div>
);
}
export default App;
五、节流
通过设置 options.throttleWait
, 进入节流模式,此时如果频繁触发 run
或者 runAsync
,则会以节流策略进行请求。
节流开始前执行
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error, run } = useRequest(getName, {
manual: true,
throttleWait: 3000,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("嘻嘻")}>run</button>
{render()}
</div>
);
}
export default App;
节流开始后执行
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error, run } = useRequest(getName, {
manual: true,
throttleWait: 3000,
throttleLeading:false
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("嘻嘻")}>run</button>
{render()}
</div>
);
}
export default App;
六、屏幕聚焦重新请求
通过设置 options.refreshOnWindowFocus
, 在浏览器窗口 refocus
和 revisible
时,会重新发起请求。
import React, { useState } from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error } = useRequest(getName, {
defaultParams: ["哈哈"],
refreshOnWindowFocus: true,
focusTimespan: 4000,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return <div>{render()}</div>;
}
export default App;
七、错误重试
语法
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("哈哈");
}, 2000);
});
};
const { data, loading, error } = useRequest(getName, {
retryCount: 3,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return <div>{render()}</div>;
}
export default App;
八、Loading Delay
通过设置 options.loadingDelay
, 可以延迟 loading
变成 true
的时间,有效防止闪烁
语法
import React from "react";
import { useRequest } from "ahooks";
function App() {
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
// reject("获取失败");
}, 4000);
});
};
const { data, loading, error, run } = useRequest(getName, {
manual: true,
loadingDelay: 1000,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => run("哈哈")}>
{loading ? "获取中…………" : "run"}
</button>
{render()}
</div>
);
}
export default App;
九、SWR (stale-while-revalidate)
十、缓存
十一、Ready
useRequest 提供了一个 options.ready 参数,当其值为 false 时,请求永远都不会发出。其具体行为如下:
-
当
manual=false
自动请求模式时,每次ready
从false
变为true
时,都会自动发起请求,会带上参数options.defaultParams
。 -
当
manual=true
手动请求模式时,只要ready=false
,则通过run/runAsync
触发的请求都不会执行。
自动模式
import React, { useState } from "react";
import { useRequest } from "./ahooks";
function App() {
const [ready, setReady] = useState(false);
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 4000);
});
};
const { data, loading, error } = useRequest(getName, {
ready,
defaultParams:['哈哈哈']
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => setReady(!ready)}>改变 ready 为 true</button>
{render()}
</div>
);
}
export default App;
手动模式
import React, { useState } from "react";
import { useRequest } from "./ahooks";
function App() {
const [ready, setReady] = useState(false);
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 4000);
});
};
const { data, loading, error, run } = useRequest(getName, {
ready,
manual: true,
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => setReady(!ready)}>改变 ready 为 true</button>
<button onClick={() => run("哈哈")}>run</button>
{render()}
</div>
);
}
export default App;
十二、依赖刷新
useRequest 提供了一个 options.refreshDeps
参数,当它的值变化后,会重新触发请求。
基础依赖刷新
import React, { useState } from "react";
import { useRequest } from "ahooks";
function App() {
const [id, setId] = useState(0);
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error } = useRequest(getName, {
refreshDeps: [id],
defaultParams: ["哈哈"],
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => setId(id + 1)}>改变 id</button>
{render()}
</div>
);
}
export default App;
改变依赖刷新行为
import React, { useState } from "react";
import { useRequest } from "./ahooks";
function App() {
const [id, setId] = useState(0);
const getName = (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("柏拉文" + params);
}, 2000);
});
};
const { data, loading, error, run } = useRequest(getName, {
refreshDeps: [id],
defaultParams: [id],
refreshDepsAction() {
run(id);
},
});
const render = () => {
if (loading) {
return <div>加载中…………</div>;
}
if (error) {
return <div>{error}</div>;
}
return <div>{data}</div>;
};
return (
<div>
<button onClick={() => setId(id + 1)}>改变 id</button>
{render()}
</div>
);
}
export default App;