Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 使用useQuery和useEffect进行简单搜索_Reactjs_Graphql_Apollo - Fatal编程技术网

Reactjs 使用useQuery和useEffect进行简单搜索

Reactjs 使用useQuery和useEffect进行简单搜索,reactjs,graphql,apollo,Reactjs,Graphql,Apollo,我有一个相当复杂的组件,现在我正在尝试实现一个搜索,用户可以在其中键入内容并过滤结果 // query const GET_ACCOUNTS = gql` query accounts{ accounts{ id name status company{ id name } } } `; 问题是,当我开始在搜索字段中键入内容时,我会查看我的搜索结果,当我键入一个字符时,它会

我有一个相当复杂的组件,现在我正在尝试实现一个搜索,用户可以在其中键入内容并过滤结果

// query

  const GET_ACCOUNTS = gql`
  query accounts{
    accounts{
      id
      name
      status
      company{
        id
        name
      }
    }
  }
`;
问题是,当我开始在搜索字段中键入内容时,我会查看我的
搜索结果
,当我键入一个字符时,它会被过滤,但当我键入下一个字符时,它会中断

TypeError: Cannot read property 'filter' of undefined

而且,即使我键入了一个字母,它也不会显示在视图中。

根据您的数据,
搜索结果的初始值是一个带有
帐户
键的字典。但是,当您在
useffect
部分中更新它时,它将更改为一个列表:

useEffect(() => {
    if (searchTerm) {
      const results = searchResults.accounts.filter((c => c.name.toLowerCase().includes(searchTerm)))

      // This changes the value of searchResults to an array
      setSearchResults(results)
    }
}, [searchTerm])
当在
useffect
中调用
setSearchResults
时,
searchResults
的值将从一个对象更改为一个数组:

由此:

搜索结果={ 账户:[ ... ] }

为此:

搜索结果=[ ... ]

这就是为什么它会引发
TypeError:在第一次搜索后无法读取未定义的
的属性“filter”,因为不再有
帐户

要解决这个问题,您需要在
搜索结果的数据类型上保持一致,最好首先将其列为一个列表。您可以在
onCompleted
部分中执行此操作:

const { loading } = useQuery(GET_ACCOUNTS, {
    fetchPolicy: "no-cache",
    skip: userType !== 'OS_ADMIN',
    onCompleted: (data) => setSearchResults(data.accounts || [])
});
请注意,我们将
searchResults
设置为
accounts
值。之后,您还需要了解如何访问
搜索结果

{searchResults &&
  searchResults.map(c => {
    return (
        ...renderhere
    )
  })
}
您的
useffect
将如下所示:

useEffect(() => {
    if (searchTerm) {
        const results = searchResults.filter((c => c.name.toLowerCase().includes(searchTerm)))
        setSearchResults(results)
    }
}, [searchTerm])
提示:

您可能需要将
搜索结果
重命名为
帐户
,以使其更清晰。还请注意,在第一次搜索之后,您的选项将仅限于以前的搜索结果,因此您可能还希望将所有帐户存储在不同的变量中:

const [allAccounts, setAllAccounts] = useState([])
const [searchedAccounts, setSearchedAccounts] = useState([])

// useQuery
const { loading } = useQuery(GET_ACCOUNTS, {
    fetchPolicy: "no-cache",
    skip: userType !== 'OS_ADMIN',
    onCompleted: (data) => {
      setAllAccounts(data.accounts || [])
      setSearchedAccounts(data.accounts || [])
    }
});


// useEffect
useEffect(() => {
    if (searchTerm) {
        // Notice we always search from allAccounts
        const results = allAccounts.filter((c => c.name.toLowerCase().includes(searchTerm)))
        setSearchedAccounts(results)
    }
}, [searchTerm])

你能从get查询中给出
searchResults
的初始值吗?@RieljunLiguid刚刚添加了一个示例,但是有不止一个,所以当我渲染输出时,我会做如下操作:
{searchedAccounts.map(()=>{return}}
,如果是这样的话,如果
searchedAccounts
中没有任何内容,如何使其映射到
allAccounts
?这意味着我想在查询运行后提取完整的帐户列表,但当每个要筛选的字母都输入了搜索词时,我就开始筛选它,然后显示它们。如果搜索词中没有任何内容,则显示全部。希望这是有意义的。如果是这样的话,你可以从
allAccounts
设置
searchedAccounts
的值,类似这样:
setSearchedAccounts(allAccounts)
好的,那么我将按照提示中的建议进行设置。因此,我是否需要修改
useffect
来执行此操作?在我的渲染中,我正在使用
searchedAccounts&&searchedAccounts.map
我尝试添加另一个
useffect
但它不会更改渲染视图:
useffect(()=>{if(searchedAccounts){setSearchedAccounts(searchedAccounts)},[searchedAccounts])
因此,包括
所有账户
不起作用,但添加
搜索账户
起作用了!非常感谢你的帮助!
useEffect(() => {
    if (searchTerm) {
      const results = searchResults.accounts.filter((c => c.name.toLowerCase().includes(searchTerm)))

      // This changes the value of searchResults to an array
      setSearchResults(results)
    }
}, [searchTerm])
const { loading } = useQuery(GET_ACCOUNTS, {
    fetchPolicy: "no-cache",
    skip: userType !== 'OS_ADMIN',
    onCompleted: (data) => setSearchResults(data.accounts || [])
});
{searchResults &&
  searchResults.map(c => {
    return (
        ...renderhere
    )
  })
}
useEffect(() => {
    if (searchTerm) {
        const results = searchResults.filter((c => c.name.toLowerCase().includes(searchTerm)))
        setSearchResults(results)
    }
}, [searchTerm])
const [allAccounts, setAllAccounts] = useState([])
const [searchedAccounts, setSearchedAccounts] = useState([])

// useQuery
const { loading } = useQuery(GET_ACCOUNTS, {
    fetchPolicy: "no-cache",
    skip: userType !== 'OS_ADMIN',
    onCompleted: (data) => {
      setAllAccounts(data.accounts || [])
      setSearchedAccounts(data.accounts || [])
    }
});


// useEffect
useEffect(() => {
    if (searchTerm) {
        // Notice we always search from allAccounts
        const results = allAccounts.filter((c => c.name.toLowerCase().includes(searchTerm)))
        setSearchedAccounts(results)
    }
}, [searchTerm])