[英]Filter in react query not working properly on first attempt
我正在尝试使用过滤器从数组中只获取女性,但在第一次尝试时,react 查询返回整个数组,之后它工作正常。 知道我必须添加或删除什么属性,所以这种副作用消失了。 这是我的代码:
import React, { useState } from "react";
import { useQuery } from "react-query";
import getPersonsInfo from "../api/personCalls";
export default function Persons() {
const [persons, setPersons] = useState([]);
const { data: personData, status } = useQuery("personsData", getPersonsInfo, {
onSuccess: (data) => {
setPersons(data.data);
},
onError: (error) => {
console.log(error);
}
});
const getFemaleOnlyHandler = () => {
const result = personData.data.filter(
(person) => person.gender === "female"
);
setPersons(result);
};
return (
<>
<button onClick={getFemaleOnlyHandler}>Female only</button>
{status === "loading" ? (
<div>Loading ... </div>
) : (
<div>
{persons.map((person) => (
<div>
<p>{person.name}</p>
<p>{person.lastName}</p>
<p>{person.address}</p>
<p>{person.gender}</p>
<p>{person.country}</p>
<p>{person.city}</p>
</div>
))}
</div>
)}
</>
);
}
我在代码沙箱中添加了完整代码: https://codesandbox.io/s/relaxed-drake-4juxg
我认为您犯了将数据从反应查询复制到本地 state 的错误。 这个想法是 react-query是state 管理器,所以 react-query 返回的数据真的是你所需要的。
您在代码框中遇到的可能只是refetchOnWindowFocus
。 所以你关注 window 并单击按钮,react-query 将执行后台更新并覆盖您的本地 state。 这是我刚才提到的“复制”的直接结果。
您要做的实际上只是存储用户选择,并即时计算其他所有内容,如下所示:
const [femalesOnly, setFemalesOnly] = React.useState(false)
const { data: personData, status } = useQuery("personsData", getPersonsInfo, {
onError: (error) => {
console.log(error);
}
});
const getFemaleOnlyHandler = () => {
setFemalesOnly(true)
};
const persons = femalesOnly ? personData.data.filter(person => person.gender === "female") : personData.data
然后,您可以在 people 中显示您拥有的任何内容,这将始终是最新的,即使后台更新会产生更多persons
。 如果计算(过滤)很昂贵,您还可以使用useMemo
来记忆它(仅在personData
或femalesOnly
更改时计算它 - 但这可能是过早的优化。
我对react-query
并不完全熟悉,但是问题很可能是每次组件更新时它都会重新获取(异步)。 由于setPersons()
触发更新(即设置状态),它会将新persons
state 更新为过滤后的女性列表,然后再次触发对所有人员的获取,该人员再次返回并将persons
state 设置回完整列表(即。看看当你点击女性过滤器按钮然后离开它时会发生什么)。
在 React 中有一种更惯用的方法来实现这一点,即保持“单一事实来源” (即所有人)并根据一些本地 ui state 动态过滤。
例如,请参见下面的data
成为事实来源的地方,而persons
是该事实来源的计算值。 这样做的好处是,如果您的原始data
发生更改,您不必手动(阅读:强制)将其更新为仅限女性。 这就是人们经常谈论的“单向数据流”和“反应性” ,老实说,这就是 React 的原因。
const { data = { data: [] }, status } = useQuery(
"personsData",
getPersonsInfo,
{
onSuccess: (data) => {},
onError: (error) => {
console.log(error);
}
}
);
const [doFilterFemale, setFilterFemale] = useState(false);
const persons = doFilterFemale
? data.data.filter((person) => person.gender === "female")
: data.data;
https://codesandbox.io/s/vigorous-nobel-9n117?file=/src/Persons/persons.jsx
这是假设您总是从 json 文件加载。 在实际应用程序设置中,给定您控制的后端,我始终建议在服务器端实现过滤、排序和分页,否则您将被迫在客户端过度获取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.