跳到主要内容

语法

一、自动请求


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 来触发执行。

runrunAsync 的区别在于:

  • 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 提供了 refreshrefreshAsync 方法,使我们可以使用上一次的参数,重新发起请求。

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, 在浏览器窗口 refocusrevisible 时,会重新发起请求。

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 时,请求永远都不会发出。其具体行为如下:

  1. manual=false 自动请求模式时,每次 readyfalse 变为 true 时,都会自动发起请求,会带上参数 options.defaultParams

  2. 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;