【发布时间】:2021-03-16 22:56:45
【问题描述】:
我有一阵子想不通...(我是 React 新手,还在学习)
我需要使用两个 API:
第一个包含所有客户订单信息
{ "orders": [{ "id": "480cb439", "name": "订单名称", "clientId": 4 }, ... ] }
第二个根据第一个 API 的参数
{ "client": { "id": 4, "name": "John Doe" } }
目标非常简单 - 从两个 API 获取信息,将其呈现为包含订单和客户端信息的简单卡片。如何使用钩子在 React 中使用 async/await 执行此操作?
我的代码如下:
import React, { useState } from 'react';
import { useApi } from "./services/UseAPI";
import { Loading } from "./components/LoadingComponent";
import { Card, CardImg, CardText, CardBody, CardTitle, CardSubtitle, Button, CardHeader } from 'reactstrap';
function App() {
const [searchTerm, setSearchTerm] = React.useState("");
const handleChange = event => {
setSearchTerm(event.target.value);
};
const Clients = ({clientId}) => {
const url = `Clients API endpoint` + clientId;
const param = "client";
const { data, isLoading, hasError } = useApi(url, [], param);
if (isLoading) return <Loading />;
if (hasError)
return (
<div>
<p>Failed to fetch worker info ????</p>
</div>
);
if (data.name !== undefined && data.name.toLowerCase().includes(searchTerm.toLocaleLowerCase()))
return (
<div className="row">
<div className="col-7 my-auto text-left">
<div>{data.name}</div>
</div>
</div>
);
else return null;
}
const Orders = () => {
const url = `Orders API endpoint`;
const param = "orders";
const { data, isLoading, hasError } = useApi(url, [], param);
if (isLoading) return <Loading />;
if (hasError)
return (
<div>
<p>Failed to fetch work orders ????</p>
</div>
);
return (
data.map(order =>
<div className="col-6">
<Card key={order.id} className="text-center m-5">
<CardHeader tag="h5">{order.name}</CardHeader>
<CardBody>
<Clients clientId={order.clientId} searchTerm={searchTerm} />
</CardBody>
</Card>
</div>
)
);
}
return (
<div className="row">
<input className="col-10 offset-1" type="text" placeholder="Filter by client name..." value={searchTerm} onChange={handleChange} />
<Orders />
</div>
);
}
export default App;
我用于从 API 获取的自定义钩子:
import { useEffect, useState } from "react";
export const useApi = (initialUrl, initialData, param) => {
const [url, setUrl] = useState(initialUrl);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);
const [fetchedData, setFetchedData] = useState(initialData);
useEffect(() => {
let unmounted = false;
const handleFetchResponse = response => {
if (unmounted) return initialData;
setHasError(!response.ok);
setIsLoading(false);
return response.ok && response.json ? response.json() : initialData;
};
const fetchData = () => {
setIsLoading(true);
return fetch(url)
.then(handleFetchResponse)
.catch(handleFetchResponse);
};
if (initialUrl && !unmounted)
fetchData().then(data => !unmounted && setFetchedData(data[param]));
return () => {
unmounted = true;
};
}, [url]);
return { isLoading, hasError, setUrl, data: fetchedData };
};
【问题讨论】:
-
可以并行调用还是第二个调用依赖于第一个响应中的信息?
-
第二次调用取决于第一次调用的信息...
标签: reactjs async-await react-hooks fetch