首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用React和阿波罗客户端在中实现搜索功能?

如何使用React和阿波罗客户端在中实现搜索功能?
EN

Stack Overflow用户
提问于 2019-04-28 13:12:39
回答 3查看 6.3K关注 0票数 3

我尝试使用React Hooks和GraphQL-阿波罗客户端在我的管理系统中实现搜索功能。虽然界面显示成功,但当我按下“搜索”按钮时,会出现一个错误,名为:

无效钩子呼叫。钩子只能在函数组件的主体内调用。

我很确定useQuery是在函数中被调用的,所以我不知道是什么导致了这一点。其他功能,如显示所有用户和添加新用户,运行良好。

我尝试了几种方法来实现搜索功能,并在网上搜索,但仍然无法解决。这是我第一次遇到反应-胡克斯也是。

下面是我在searchUser组件中的当前代码

代码语言:javascript
复制
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。我的问题有什么问题吗?以下是查询:

代码语言:javascript
复制
const searchUserQ = gql`
query User($name: String!){
    user(name: $name){
        id
        name
        email
    }
 }
`;

感谢并感谢您的帮助!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-04-28 16:00:04

根据钩子规则

不要从常规的JavaScript函数调用钩子。相反,你可以: ✅从function函数组件调用钩子。 ✅从自定义钩子调用钩子(我们将在下一页了解它们)。

如果需要手动调用对事件的查询ins响应,请直接使用阿波罗客户端。您可以使用useApolloClient在组件中获取客户端的实例:

代码语言:javascript
复制
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,如下所示:

代码语言:javascript
复制
const SearchUserForm = () => {
  const [name, setName] = useState('')
  const { data, loading, error } = useQuery(searchUserQ, {
    variables: { name },       
  });
  ...
    return (
      ...
      <button onClick={async (event) => {
        setName(event.target.value)
        ...
      }} />
票数 8
EN

Stack Overflow用户

发布于 2020-03-15 08:10:34

您可以使用useLazyQuery方法并将数据对象公开给整个组件。

代码语言:javascript
复制
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方法将为您提供一个错误。因为在组件呈现时,它将尝试在没有所需参数的情况下直接运行该查询,因为在这段时间内它还不可用。

票数 1
EN

Stack Overflow用户

发布于 2019-04-29 08:32:53

我发现了第二个答案的问题,应该在执行它之前包装一个if-语句,下面是完整的代码:

代码语言:javascript
复制
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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55890604

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档