重新提取后,apollo graphql UI不会更新

时间:2018-11-26 04:03:19

标签: reactjs apollo

在react登录组件中,一旦登录成功,我想重新获取和更新navbar组件。

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(),
});

4 个答案:

答案 0 :(得分:1)

尝试添加

 options: {
      awaitRefetchQueries: true
 },

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

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

答案 1 :(得分:0)

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

对于我来说,如果用户未登录,在查询getMe时什么也不返回或返回错误是很典型的事情。

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

解决我的问题的方法是不给errorPolicy

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

由于我正在使用HOC,因此这是我的解决方案。

答案 2 :(得分:0)

我遇到了一个问题,即调用 data 函数后 useQuery 钩子中的 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 :(得分:0)

查看有关此问题的 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 的新值可能要到下一次渲染时才会出现。