React Hooks-处理异步api调用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Hooks-处理异步api调用相关的知识,希望对你有一定的参考价值。
我正在尝试建立一个自定义钩子来处理项目中的所有api提取。我可以成功拨打电话并存储数据,但只能在第一个电话之后进行。我非常有信心,由于比赛条件和异步的性质,第一次调用不会返回任何内容。
这是我的钩子:
import { useState, useEffect } from 'react'
import api from 'services/api'
const useHopServiceApi = () => {
const [data, setData] = useState([])
const [url, setUrl] = useState('')
const [body, setBody] = useState({})
const [isLoading, setIsLoading] = useState(false)
const [isError, setIsError] = useState(false)
useEffect(() => {
const fetchData = async () => {
setIsError(false)
setIsLoading(true)
try {
const result = await api.post(url, body)
setData(result.d)
} catch (error) {
setIsError(true)
}
setIsLoading(false)
}
if (url && body) {
fetchData()
}
}, [url, body])
return [{ data, isLoading, isError }, setUrl, setBody]
}
export default useHopServiceApi
及其被调用的组件:
const HomePage = (props) => {
const [{ data, isLoading, isError }, doFetch, setBody] = useHopServiceApi()
const handleClickSelectInterests = () => {
setBody({ count: 1 })
doFetch('/GetPopularCities')
console.log('data:', data)
}
}
[当我单击按钮(触发api调用)时,数据作为一个空数组注销,但是在随后的单击中,数据被填充了。
第一次单击后看不到数据的原因是,在调用doFetch
之后,您还没有数据。
第二次单击按钮以调用handleClickSelectInterests
数据已记录,但这是来自第一个渲染的数据。您可以很好地渲染更新的数据,但是不能在handleClick
函数中记录最新的数据。
这里是一个例子,说明我的意思:
根组件:
import React from "react";
import ReactDOM from "react-dom";
import useHopServiceApi from "./useHopServiceApi";
import "./styles.css";
function App() {
const [{ data, isLoading, isError }, doFetch] = useHopServiceApi();
console.log("Data in render!", data);
const handleClick = () => {
doFetch("/fakeUrl");
// Data logged below will show the data from the previous request, not the latest
console.log("Data in handle click!", data);
};
return (
<div className="App">
{isLoading && <div>Is loading!</div>}
<button onClick={handleClick}>Simulate fetch!</button>
{data && <div>Data! {data}</div>}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
您的钩子:
import { useState, useEffect } from "react";
let numClick = 1;
const simulatedFetch = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve(`Fetch request data for request number ${numClick}`);
numClick++;
}, 2000);
});
};
const useHopServiceApi = () => {
const [data, setData] = useState([]);
const [url, setUrl] = useState("");
const [body, setBody] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsError(false);
setIsLoading(true);
try {
const result = await simulatedFetch();
console.log("new result!", result);
setData(result);
setUrl("");
} catch (error) {
setIsError(true);
}
setIsLoading(false);
};
if (url) {
fetchData();
}
}, [url, body]);
return [{ data, isLoading, isError }, setUrl, setBody];
};
export default useHopServiceApi;
上面的示例显示,即使您无法在handleClick
函数中记录数据,也可以在render函数中使用最新数据。>
从docs:
以上是关于React Hooks-处理异步api调用的主要内容,如果未能解决你的问题,请参考以下文章
React拓展 - setState - 路由组件懒加载 - Hooks - Fragment - Context - PureComponent - 插槽 - 错误边界 - 组件通信方式总结(代码片
如何使用 React Hooks 和 Context API 正确地将来自 useEffect 内部调用的多个端点的数据添加到状态对象?
使用 React Hooks 编写 REST API 时如何重用代码?
转学习使用 Node.js 中 async-hooks 模块