bln*_*nks 1 javascript reactjs next.js react-query
在我的第一个Next.js项目中,我有一个在服务器端呈现的文章组件。我想从客户端获取文章标签,否则我会得到太多 DOM 元素。所以这就是我想出的:
const ArticlesPage = () => {
const [tags, setTags] = useState([])
const { isLoading, isError, data, error } = useQuery('tags', getTags, {
onSuccess: () => setTags(data)
}
//...
})
console.log('tags are:', tags)
return (
<>
...
{!isLoading && !isError &&
<TagsComponent tags={tags} />
}
{isLoading &&
<div> Loading tags...</div>
}
{isError &&
<div> Error fetching tags</div>
}
</>
Run Code Online (Sandbox Code Playgroud)
问题是标签异想天开地呈现在文章页面上,也就是说,当我刷新页面时,它们不会显示,但当我重新关注页面时,标签会显示。我也没有看到任何Loading或Error正在渲染。所以我很困惑这里发生了什么?
我怎样才能解决这个问题?
正如另一个答案中提到的,您不应该使用 setState 来存储从 API 返回的数据。这样做将使您的缓存管理非常难以维护和推理。相反,您应该使用状态来存储结果的筛选选项,然后使用该状态来筛选数据。
假设您的 API 使用有效负载来过滤响应,我们可以将要发送的有效负载存储在“过滤器”状态变量中,并将其用作我们的查询密钥。
它们的关键函数getTags应该接受{queryKey: [,filter]}作为其参数,并且应该将过滤器传递给 api 调用。filter然后你可以通过和属性在 TagsComponent 中控制它setFilter。
const ArticlesPage = () => {
const [filter, setFilter] = useState({});
const { isLoading, isError, data: tags, error } = useQuery(
["tags", filter],
getTags,
);
console.log("tags are:", tags);
if(isError) return <div>Error fetching tags</div>;
if(isLoading) return <div>Loading tags...</div>;
return <TagsComponent
tags={tags}
filter={filter}
setFilter={setFilter} />;
};
Run Code Online (Sandbox Code Playgroud)
由于您不能依赖 API 来过滤结果,因此您需要在响应返回后过滤结果。再次假设您有filter用户指定的某种状态,以及一个filterTags(filter, tags) => filteredTags根据该状态过滤标签的函数,我们可以通过以下方式将它们组合在一起:
const ArticlesPage = () => {
const [filter, setFilter] = useState({});
const { isLoading, isError, data: tags, error } = useQuery("tags", getTags);
const filteredTags = useMemo(() => filterTags(filter, tags), [tags, filter]);
if(isError) return <div>Error fetching tags</div>;
if(isLoading) return <div>Loading tags...</div>;
return <TagsComponent
tags={filteredTags}
filter={filter}
setFilter={setFilter} />;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1380 次 |
| 最近记录: |