重新获取后 apollo graphql UI 未更新

Posted

技术标签:

【中文标题】重新获取后 apollo graphql UI 未更新【英文标题】:apollo graphql UI is not updating after refetch 【发布时间】:2019-04-27 17:10:57 【问题描述】:

在一个反应​​登录组件中,一旦登录成功,我想重新获取和更新导航栏组件。

const loginUser = () => 
    props.mutate(
      variables: 
        input:  email, password ,
      ,
      refetchQueries: [ query: GET_ME ],
    );
  ;

我可以在网络选项卡中看到登录和重新获取,并且都返回 200 并具有正确的状态。但是导航栏仍然显示旧数据。

这是我的导航栏组件。

export const Header = props => 
  return <div>Header JSON.stringify(props.data)</div>;
;

export default graphql(GET_ME)(Header);

还有 apolloClient:

export const client = new ApolloClient(
  link: createHttpLink(
    credentials: 'include',
    uri: 'http://localhost:8080/api/graphql',
  ),
  cache: new InMemoryCache(),
);

【问题讨论】:

如果您找到解决方案,请更新!遇到类似的问题 【参考方案1】:

查看有关此问题的 GitHub 问题,refetch 似乎存在一些小故障。就我而言,它将最新数据放入缓存中,但没有触发 React 刷新。

我是这样解决的:

const loading = useRef(false);
const dataToDisplay = useRef([]]);
const [toggleRefresh, setToggleRefresh] = useState(false);

useEffect(() => 
    loading.current = true;
    client.query(
        query: MY_QUERY,
        variables: "myVar": myVar,
        fetchPolicy: 'network-only',
        skip: loading.current
    ).then((result) => 
        loading.current = false;
        dataToDisplay.current = result.data.dataToDisplay;
        setToggleRefresh(!toggleRefresh); //cheesy but it seems to work
    );
, [varThatTriggersRefetchWhenChanged]);

您可能会说,“但这没有意义。skip 设置为 loading.current,而此时 loading.current 必须为真。”

根据其他 SO 帖子,我认为 useRef 的新值可能要到下一次渲染才会出现。

【讨论】:

【参考方案2】:

我遇到了一个问题,即 useQuery 挂钩中的 data 在调用 refetch 函数后没有更新。就我而言,问题的原因是 onError 回调。删除它并使用 useEffect 挂钩来观察 error 变量解决了这个问题。

const  data, loading, refetch  = useQuery(GET_LIST, 
    variables: 
        offset: 0,
        limit: 50,
    ,
    onError: () => 
       // handle error here
    ,
)

改为:

const  data, loading, refetch, error  = useQuery(GET_LIST, 
    variables: 
        offset: 0,
        limit: 50,
    ,
)

useEffect(() => 
    if(error)
        // handle error here
    
, [error])

【讨论】:

【参考方案3】:

约翰所说的可能是某些人的解决方案,但不是我的。

对我来说,如果用户未登录,则在查询 getMe 时得到什么都没有返回或错误是很常见的。

因此,下一次调用不会重置缓存,这会使整个系统出错。

我的问题的解决方案是给一个errorPolicy 无。

export const isAuth = compose(
  graphql(GET_ME, 
    options: 
      fetchPolicy: 'cache-first',
      errorPolicy: 'ignore',
    ,
  )
);

由于我使用的是 HOC,这是我的解决方案。

【讨论】:

【参考方案4】:

尝试添加

 options: 
      awaitRefetchQueries: true
 ,

到 refetchQueries 和变量旁边的 props.mutate。

使用 options.refetchQueries 重新获取的查询是异步处理的,这意味着默认情况下它们不一定在突变完成之前完成。将 options.awaitRefetchQueries 设置为 true 将确保重新获取的查询在突变被认为完成(或解决)之前完成。 options.awaitRefetchQueries 默认为 false。

【讨论】:

这可能已经为我解决了这个问题,但我所做的是通过使用 fetchPolicy 和 errorPolicy

以上是关于重新获取后 apollo graphql UI 未更新的主要内容,如果未能解决你的问题,请参考以下文章

删除突变后不重新获取查询(Apollo Graphql & Nextjs)

Apollo Graphql:避免在重新获取期间加载指示器

使用 Apollo 重新获取部分 GraphQL 查询的最佳实践?

React + Apollo:GraphQL 错误数组未传递到组件中

使用 Apollo-Client 重新获取查询会引发错误

React、Apollo 2、GraphQL、身份验证。登录后如何重新渲染组件