如何使用 React-Hooks 和 Apollo Client 在 React-GraphQL 中实现搜索功能?
How to implement Search Function in React-GraphQL using React-Hooks and Apollo Client?
我尝试使用 React-Hooks 和 GraphQL-Apollo Client 在我的管理系统中实现搜索功能。当界面显示成功时,当我按下 'Search' 按钮时,出现了一个名为:
的错误
Invalid hook call. Hooks can only be called inside of the body of a function component.
我很确定 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
似乎是 return undefined
每次我执行查询。我的查询有问题吗?
这是查询:
const searchUserQ = gql`
query User($name: String!){
user(name: $name){
id
name
email
}
}
`;
感谢并感谢您的帮助!
Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).
如果您需要在响应事件时手动调用查询,请直接使用 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)
...
}} />
我发现我的第二个答案有问题,应该在执行之前包装一个 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;
您可以使用 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 方法将 仅在点击时执行 .
此时您可以将 'name' 值作为参数传递。
例如,如果您要使用 useQuery,并且有一个查询中需要的参数(即 String!
),useQuery 方法将为您提供有一个错误。因为在组件渲染时,它会尝试 运行 直接查询而不需要必需的参数,因为在那个时间段它还不可用。
我尝试使用 React-Hooks 和 GraphQL-Apollo Client 在我的管理系统中实现搜索功能。当界面显示成功时,当我按下 'Search' 按钮时,出现了一个名为:
的错误Invalid hook call. Hooks can only be called inside of the body of a function component.
我很确定 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
似乎是 return undefined
每次我执行查询。我的查询有问题吗?
这是查询:
const searchUserQ = gql`
query User($name: String!){
user(name: $name){
id
name
email
}
}
`;
感谢并感谢您的帮助!
Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).
如果您需要在响应事件时手动调用查询,请直接使用 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)
...
}} />
我发现我的第二个答案有问题,应该在执行之前包装一个 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;
您可以使用 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 方法将 仅在点击时执行 .
此时您可以将 'name' 值作为参数传递。
例如,如果您要使用 useQuery,并且有一个查询中需要的参数(即 String!
),useQuery 方法将为您提供有一个错误。因为在组件渲染时,它会尝试 运行 直接查询而不需要必需的参数,因为在那个时间段它还不可用。