reactjs React/GraphQL提升查询?

iswrvxsc  于 2023-03-01  发布在  React
关注(0)|答案(2)|浏览(127)

所以可能有一些我不知道的明显的答案,我对GraphQL没有太多的经验,所以如果这是一个愚蠢的问题,请提前道歉。
基本上,我有一个组件,在其中从GraphQL获取一些数据,然后将该数据传递给过滤数组的函数,然后将过滤结果传递给子组件,大致如下所示

  • 子组件.tsx*
const { loading, error, data } = useQuery(SOME_RANDOM_QUERY, {variables: { id: Id, number: Value1 }})

const filteredItems: Item[] = data && getFilteredItems(data.items.nodes)
.
.
.
<SomeComponent itemsArray={filteredItems} />

这很有效。然而,我需要另一个兄弟组件中的GraphQL数据,所以我必须提升这个查询。我这样做了:

  • 父组件.tsx*
const queryResults = useQuery(SOME_RANDOM_QUERY, {variables: { id: Id, number: Value1 }})
.
.
.
<ChildComponent itemsList={queryResults?.data?.items?.nodes} />
  • 子组件.tsx*
const ChildComponent: React.FC<{
  itemsList: Item[]
}> = ({ itemsList }) => {

const filteredItems: Item[] = itemsList && getFilteredItems(itemsList)
    .
    .
    .
    <SomeComponent itemsArray={filteredItems} />

现在这不起作用了,它抛出了一个错误,说它“无法读取 SomeComponent 中未定义的属性”。这让我认为代码在查询结果返回之前就运行了。
你知道是什么原因造成的吗?为什么当查询在同一个文件中时,它工作,但现在当它通过 prop 传递时,它突然不工作了?

kmbjn2e3

kmbjn2e31#

由于graphql基本上是一个异步API调用(组件无论api调用是否结束都将呈现),因此即使在未接收到数据时,子组件也将呈现,这意味着在检索到数据之前,将传递undefined
您可以同时添加加载组件

if(loading){
  return <loadingComponent/>
}

return <SomeComponent itemsArray={filteredItems}/>
yuvru6vn

yuvru6vn2#

这里有几点:
1.渲染发生在useQuery返回数据之前,这是正确的-这就是loading变量存在的原因。当loadingtrue时,不应渲染依赖于从查询返回的数据的内容,因为data通常为undefined
1.如果你打算在渲染之前过滤数据或者对数据进行其他操作,那么使用useMemo来记忆操作是一个很好的习惯。
牢记上述内容:

const Parent = () => {
  …
  const { loading, error, data } = useQuery(SOME_RANDOM_QUERY, {variables: { id: Id, number: Value1 }})
  const filteredItems = useMemo(()=> data ? getFilteredItems(data.items.nodes) : [])
  
  if (loading) return <Loading /> // typically a spinner
  else if (error) return <Error error={error} /> // some error handling component
  else return (
    <>
      <Child1 itemList={filteredItems] />
      <Child2 itemList={filteredItems] />
    </>
  )
}

相关问题