【发布时间】:2020-04-23 14:33:52
【问题描述】:
我正在尝试使用从 GraphQL 查询中收集的数据更新状态。 我尝试过类似于https://www.apollographql.com/docs/react/data/queries/ 标题为“手动执行查询”下的官方教程。
export default function SearchField() {
const [
searchInput,
setSearchInput
] = useState('');
const [
drinks,
setDrinks
] = useState(null);
const handleSubmit = (e) => {
e.preventDefault();
getDrinks({ variables: { cocktailName: searchInput } });
};
const [
getDrinks,
{ loading, data }
] = useLazyQuery(MULTIPLE_COCKTAILS_BY_NAME_QUERY);
if (loading)
return (
<div className="justify-content-center">
<p>Loading ...</p>
</div>
);
if (data && data.multipleCocktailsByName) {
setDrinks(data.multipleCocktailsByName);
}
return (...)
return 之前的最后一部分使组件崩溃,并显示“错误:重新渲染过多。React 限制了渲染次数以防止无限循环。”如果我尝试像这样更新 handleSubmit 中的状态:
const handleSubmit = (e) => {
e.preventDefault();
getDrinks({ variables: { cocktailName: searchInput } });
setDrinks(data.multipleCocktailsByName);
};
然后我收到错误“无法读取未定义的属性 'multipleCocktailsByName'”。我仍然设法有条件地从查询中呈现数据,但处理状态很麻烦。我非常感谢您能帮我解决这个问题。
【问题讨论】:
-
useLazyQuery不应使用,除非您需要执行查询以响应用户操作(如点击)。不要通过自己管理状态来重新发明轮子——使用useQuery代替已经将数据公开为状态,除了加载和错误状态。 -
感谢您的意见,丹尼尔!我省略了函数的返回部分以使问题更具可读性。但是,在这种情况下,我想通过按一下按钮来使用查询,所以lazyQuery 似乎是正确的选择。
-
你应该使用钩子提供的
data。您可以按照其中一个答案的建议使用useEffect将其填充到组件状态,但这会不必要地使您的代码复杂化。 -
@ZeGeR 我更新了我的答案(现在我可以访问桌面了)——它可能会有所帮助。
标签: reactjs graphql react-hooks apollo react-apollo