如何使用 React-Hooks 和 Apollo Client 在 React-GraphQL 中实现搜索功能?
Posted
技术标签:
【中文标题】如何使用 React-Hooks 和 Apollo Client 在 React-GraphQL 中实现搜索功能?【英文标题】:How to implement Search Function in React-GraphQL using React-Hooks and Apollo Client? 【发布时间】:2019-09-17 07:48:08 【问题描述】:我尝试使用 React-Hooks 和 GraphQL-Apollo 客户端在我的管理系统中实现搜索功能。虽然界面显示成功,但当我按下“搜索”按钮时,出现一个错误,名为:
无效的挂钩调用。 Hooks 只能在函数组件内部调用。
我很确定 useQuery
是在函数内部调用的,所以我不明白是什么原因造成的。显示所有用户和添加新用户等其他功能正常。
我已经尝试了几种方法来实现搜索功能并在线搜索,但仍然无法解决。这也是我第一次遇到 React-Hooks。
这是我在 searchUser
组件中的当前代码
import React from 'react'
import useQuery from 'react-apollo-hooks';
import searchUserQ from '../queries/queries';
const SearchUserForm = () =>
let name = '';
let content;
return (
<div id="edit-user">
<div className="field">
<label htmlFor="name">Search UserName</label>
<input type="text" id="name" onChange= (event) =>
name = event.target.value />
<button onClick=(event) =>
event.preventDefault();
const data, loading, error = useQuery(searchUserQ,
variables: name: name ,
suspend: false
);
if (loading)
content = <p>Loading User...</p>
if (error)
console.log(`Error Occur: $ error `);
content = <p>Error Occur!</p>
content = data.users.map(user => (
<p key=user.id>Username: user.name ID: user.id</p>
));
>
Submit
</button>
<p> content </p>
</div>
</div>
)
export default SearchUserForm;
有人可以帮忙吗?
还有一个问题是我的data
似乎每次执行查询时都会返回undefined
。我的查询有问题吗?
以下是查询:
const searchUserQ = gql`
query User($name: String!)
user(name: $name)
id
name
email
`;
感谢并感谢您的帮助!
【问题讨论】:
【参考方案1】:根据Rules of Hooks:
不要从常规 javascript 函数中调用 Hooks。相反,您可以:
✅ 从 React 函数组件调用 Hooks。
✅ 从自定义 Hooks 调用 Hooks(我们将在下一页了解它们)。
如果您需要手动调用查询以响应事件,请直接使用 Apollo 客户端。您可以使用useApolloClient
在组件中获取客户端实例:
const SearchUserForm = () =>
const client = useApolloClient();
...
return (
...
<button onClick=async (event) =>
try
const data = client.query(
query: searchUserQ,
variables: name: event.target.value ,
);
// Do something with data, like set state
catch (e)
// Handle errors
/>
你仍然可以使用useQuery
,像这样:
const SearchUserForm = () =>
const [name, setName] = useState('')
const data, loading, error = useQuery(searchUserQ,
variables: name ,
);
...
return (
...
<button onClick=async (event) =>
setName(event.target.value)
...
/>
【讨论】:
感谢您的帮助!我已经摆脱了错误!还有一个问题,当我执行查询时,我的“数据”总是未定义,我的查询有问题吗?我已经更新了我在问题中的查询,谢谢! 我已经找到第二个问题的答案了,感谢您的帮助!【参考方案2】:您可以使用useLazyQuery 方法并将您的数据对象公开给您的整个组件。
import useLazyQuery from '@apollo/react-hooks';
// - etc. -
const SearchUserForm = () =>
// note: keep the query hook on the top level in the component
const [runQuery, data, loading, error ] = useLazyQuery(searchUserQ);
// you can now just use the data as you would regularly do:
if (data)
console.log(data);
return (
<div id="edit-user">
<div className="field">
<label htmlFor="name">Search UserName</label>
<input
type="text"
id="name"
onChange=(event) => name = event.target.value />
<button onClick=
(event) =>
event.preventDefault();
// query is executed here
runQuery(
variables: name , // note: name = property shorthand
suspend: false
)
>
// - etc. -
);
与执行 useQuery 不同,useLazyQuery 方法将仅在点击时执行。
此时您可以将“名称”值作为参数传递。
例如,如果您改用 useQuery,并且有一个查询中需要的参数(即String!
),那么 useQuery 方法将为您提供错误。因为在组件渲染时,它会尝试直接运行该查询而不需要所需的参数,因为在那段时间它还不可用。
【讨论】:
【参考方案3】:我发现我的第二个答案有问题,应该在执行之前包装一个 if 语句,这是完整的代码:
import React, useState from 'react'
import useQuery from 'react-apollo-hooks';
import searchUserQ from '../queries/queries';
const SearchUserForm = () =>
const [name, setName] = useState('');
const data, error, loading = useQuery(searchUserQ,
variables: name
);
let content;
let sName;
if (data.user !== undefined && data.user !== null)
if (loading) content = 'Loading User...'
if (error) content = `Error Occur: $error`
const user = data.user;
content = `Username: $ user.name ID: $ user.id `
return (
<div id="edit-user">
<div className="field">
<label htmlFor="name">Search UserName</label>
<input type="text" id="name" onChange=(event) =>
sName = event.target.value;
/>
<button onClick=(event) =>
setName(sName);
value=name>
Search
</button>
</div>
<div>
<p> content </p>
</div>
</div>
)
;
export default SearchUserForm;
【讨论】:
以上是关于如何使用 React-Hooks 和 Apollo Client 在 React-GraphQL 中实现搜索功能?的主要内容,如果未能解决你的问题,请参考以下文章
@apollo/react-hooks 中的 `useSubscription` 方法加载卡住
使用 Jest 模拟 @apollo/react-hooks useQuery
使用@apollo/react-hooks,react 应用程序在刷新过期时严重崩溃
使用 graphql-tools、apollo-link-schema 和 react-hooks 在模拟时总是返回 undefined