使用 React Query 从 API 中过滤获取的列表
Filtering a fetched list from an API using React Query
我(第一次)使用 React Query 来管理对 API 的调用。我正在获取发票列表,到目前为止我已经在下面的代码中成功完成了。我现在想根据每个发票对象具有的状态 属性 过滤此列表 - 它是 'paid'、'pending' 或“草稿” - 使用一系列复选框。
我该怎么做?过滤是否可以以某种方式集成到对 API 的初始调用中,以便我始终接收一组数据,或者我是否必须进行多次调用并在下面相应地呈现数据?
import React from 'react'
import {useQuery} from 'react-query'
import InvoiceLink from './InvoiceLink'
const fetchData = async () => {
const res = await fetch('http://localhost:3004/invoices');
return res.json();
};
export default function InvoiceList() {
const {data, isLoading, isError} = useQuery('invoices', fetchData);
return (
<div>
<ul>
<li><input type="checkbox" id="paid"></input><label htmlFor="paid">Paid</label></li>
<li><input type="checkbox" id="pending"></input><label htmlFor="pending">Pending</label></li>
<li><input type="checkbox" id="draft"></input><label htmlFor="draft">Draft</label></li>
</ul>
{isError && (
<p>Error</p>
)}
{isLoading && (
<p>Loading</p>
)}
<ul>
{data && data.map(item =>
<InvoiceLink key={item.id} invoice={item} />
)}
</ul>
</div>
)
}
只请求api一次,根据响应数据进行过滤,无需react-query
export default function InvoiceList() {
const {data, isLoading, isError} = useQuery('invoices', fetchData);
// filter the data here
const isPaid = data.find(...)
const isPending = data.find(...)
const isDraft = data.find(...)
return (
<div>
<ul>
<li><input type="checkbox" checked={isPaid} id="paid"></input><label htmlFor="paid">Paid</label></li>
<li><input type="checkbox" checked={isPending} id="pending"></input><label htmlFor="pending">Pending</label></li>
<li><input type="checkbox" checked={isDraft} id="draft"></input><label htmlFor="draft">Draft</label></li>
</ul>
{isError && (
<p>Error</p>
)}
{isLoading && (
<p>Loading</p>
)}
<ul>
{data && data.map(item =>
<InvoiceLink key={item.id} invoice={item} />
)}
</ul>
</div>
)
}
或者在fetchData方法中过滤数据
const fetchData = async () => {
const res = await fetch('http://localhost:3004/invoices');
const data = res.json();
return {
data: data,
isPaid: data.find(...),
isPending: data.find(...),
isDraft: data.find(...),
}
};
您可以按照 所述进行本地过滤,或者,如果您想在后端进行过滤,则需要:
- 在本地状态保持过滤条件
- 将过滤条件添加到query-key以触发自动重新获取(每次key更改时react-query重新获取)
- 将过滤条件传给fetchFn再传给后端
- 可能使用
keepPreviousData: true
以获得更好的用户体验 - 请参阅 lagged queries
类似于:
const fetchData = async (filter) => {
const res = await fetch(`http://localhost:3004/invoices/${filter}`);
return res.json();
};
const [filter, setFilter] = React.useState('all')
const {data, isLoading, isError} = useQuery(['invoices', filter], () => fetchData(filter));
此外,我想指出,由于您使用的是 fetch
,因此您需要将错误的响应转换为失败的承诺,因为 react-query 需要失败的承诺,但 fetch
不会开箱即用。请参阅 here
我(第一次)使用 React Query 来管理对 API 的调用。我正在获取发票列表,到目前为止我已经在下面的代码中成功完成了。我现在想根据每个发票对象具有的状态 属性 过滤此列表 - 它是 'paid'、'pending' 或“草稿” - 使用一系列复选框。
我该怎么做?过滤是否可以以某种方式集成到对 API 的初始调用中,以便我始终接收一组数据,或者我是否必须进行多次调用并在下面相应地呈现数据?
import React from 'react'
import {useQuery} from 'react-query'
import InvoiceLink from './InvoiceLink'
const fetchData = async () => {
const res = await fetch('http://localhost:3004/invoices');
return res.json();
};
export default function InvoiceList() {
const {data, isLoading, isError} = useQuery('invoices', fetchData);
return (
<div>
<ul>
<li><input type="checkbox" id="paid"></input><label htmlFor="paid">Paid</label></li>
<li><input type="checkbox" id="pending"></input><label htmlFor="pending">Pending</label></li>
<li><input type="checkbox" id="draft"></input><label htmlFor="draft">Draft</label></li>
</ul>
{isError && (
<p>Error</p>
)}
{isLoading && (
<p>Loading</p>
)}
<ul>
{data && data.map(item =>
<InvoiceLink key={item.id} invoice={item} />
)}
</ul>
</div>
)
}
只请求api一次,根据响应数据进行过滤,无需react-query
export default function InvoiceList() {
const {data, isLoading, isError} = useQuery('invoices', fetchData);
// filter the data here
const isPaid = data.find(...)
const isPending = data.find(...)
const isDraft = data.find(...)
return (
<div>
<ul>
<li><input type="checkbox" checked={isPaid} id="paid"></input><label htmlFor="paid">Paid</label></li>
<li><input type="checkbox" checked={isPending} id="pending"></input><label htmlFor="pending">Pending</label></li>
<li><input type="checkbox" checked={isDraft} id="draft"></input><label htmlFor="draft">Draft</label></li>
</ul>
{isError && (
<p>Error</p>
)}
{isLoading && (
<p>Loading</p>
)}
<ul>
{data && data.map(item =>
<InvoiceLink key={item.id} invoice={item} />
)}
</ul>
</div>
)
}
或者在fetchData方法中过滤数据
const fetchData = async () => {
const res = await fetch('http://localhost:3004/invoices');
const data = res.json();
return {
data: data,
isPaid: data.find(...),
isPending: data.find(...),
isDraft: data.find(...),
}
};
您可以按照
- 在本地状态保持过滤条件
- 将过滤条件添加到query-key以触发自动重新获取(每次key更改时react-query重新获取)
- 将过滤条件传给fetchFn再传给后端
- 可能使用
keepPreviousData: true
以获得更好的用户体验 - 请参阅 lagged queries
类似于:
const fetchData = async (filter) => {
const res = await fetch(`http://localhost:3004/invoices/${filter}`);
return res.json();
};
const [filter, setFilter] = React.useState('all')
const {data, isLoading, isError} = useQuery(['invoices', filter], () => fetchData(filter));
此外,我想指出,由于您使用的是 fetch
,因此您需要将错误的响应转换为失败的承诺,因为 react-query 需要失败的承诺,但 fetch
不会开箱即用。请参阅 here