0

我有一个使用 useQuery Apollo Hook 从 GraphQL API 获取数据的组件。该组件还有一个 useMemo,它具有从 useQuery Apollo 挂钩返回的数据变量作为依赖项。useMemo 最初在组件的第一次渲染上运行,因为它应该。然后,当来自 useQuery 的数据返回时,它再次运行。我通过对 useQuery 中的数据变量进行一些更改来跟进这一点。

现在,当我在另一个选项卡中重新渲染此组件时,useQuery 在初始渲染时运行一次,这是应该的,但当来自 useQuery 的数据返回时不会再次运行。注意:我在上一个选项卡中修改了 useMemo 中的数据变量,graphql api 返回了一个新的数据值,所以 useMemo 应该能够发现它,但不知何故它没有。

经我调查可能的原因:

  1. 如果“数据”变量处于函数状态,useMemo 只会在第二个选项卡中第二次运行,并且当来自 useQuery 的新数据返回并且 useQuery 重新渲染组件时不会运行,因为它对组件不可见改变。

任何帮助,将不胜感激。谢谢!

functional component: {
  const { data, loading, error: loadRolesError } = useQuery();

  const result = useMemo(()=>{
    // changing data inside here
  }, [data])
}
4

1 回答 1

0

我会在这个用例中使用 Apollo 的useReactiveVar钩子。从文档
With the useReactiveVar hook, React components can also include reactive variable values in their state directly, without wrapping them in a query.

这有几个部分,所以我在下面草拟了一个解决方案,它为所有部分提供了导入声明和从依赖项开始的可能实现

import React, { useEffect, useState,  useMemo } from 'react';
import { useReactiveVar, makeVar, useLazyQuery, InMemoryCache } from "@apollo/client"; 

制作阿波罗缓存变量

   export const dataWillUpdate = {
      // some nice flat schema data object,
      niceFlatSchemaData: {}
      };
   const dataWillUpdateVar = makeVar(dataWillUpdate);
const component = () => {
    // make the reactive apollo variable
    const dataWillUpdateVarReactive = useReactiveVar(dataWillUpdateVar);
    // memo the niceFlatSchemaData data object
    const niceFlatSchemaData = useMemo(() => userProfileVarReactive.niceFlatSchemaData, [
        dataWillUpdateVarReactive.niceFlatSchemaData,
    ]);
    // see 2 for lazy queries
    const [ getData, { data, loading, error: loadRolesError} ] = useLazyQuery();  


    useEffect(() => {
        // will update here when change to niceFlatSchemaData
        // so run query here
        getData({variables:{input:{
            // nice flat input object for the gql
        }}})
    }, [niceFlatSchemaData])

    useEffect(() => {
        // will update here when quer calls back
        // state changes for render
     
    }, [data])

}

需要在 apollo 缓存中配置变量

const globalCache = new InMemoryCache({

    typePolicies: {
        Query: {
            fields: {
                dataWillUpdate: {
                    read() {
                        return dataWillUpdateVar();
                    },
                },
            },
        },
    },
});

[1] useReactiveVar
[2]惰性查询

于 2021-08-20T11:28:31.063 回答