Apollo useQuery()-如果响应相同,则忽略“ refetch”

时间:2019-09-22 08:56:45

标签: graphql apollo react-apollo apollo-client react-apollo-hooks

我正在尝试使用Apollo客户端提取我的用户信息并遇到此问题:

我有这个Container组件,负责在呈现用户数据(而非身份验证)后将其提取。用户可能已登录,也可能未登录,查询返回viewer = nullviewer = {...usersProps}

容器发出请求const { data, refetch } = useQuery<Viewer>(VIEWER);,成功接收响应并将其保存在我用来从中读取data并将其设置为当前用户的.viewer属性中。

然后,用户可以注销,一旦这样做,我便清除了Container的用户属性setUser(undefined)(以下代码中未显示,并不重要)。

当我尝试重新登录时发生了问题:调用refetch会触发graphql http请求,但是由于它返回的数据与上一次初始登录时返回的数据相同-{{1} }会忽略它,并且不会更新useQuery()。好吧,从技术上讲不可能有更新,数据是一样的。因此,我的代码data没有第二次执行,并且用户卡在了登录页面上。

setUser(viewer);

具有相同响应的查询被忽略几乎是有道理的,所以我尝试了不同的方法,使用了回调:

  const { data, refetch } = useQuery<Viewer>(VIEWER);

  const viewer = data && data.viewer;

  useEffect(() => {
    if (viewer) {
      setUser(viewer);
    }

  }, [ viewer ]);

在这里,我完全希望Apollo使用相同的数据调用 const { refetch } = useQuery<Viewer>(VIEWER, { onCompleted: data => { if (data.viewer) { setUser(data.viewer); } } }); 回调……但是它不会那样做。因此,我对此颇为困惑-如何使Apollo对查询的onCompleted做出反应,以便可以在refetch的状态下重新填充user

1 个答案:

答案 0 :(得分:0)

在这种情况下,阿波罗的缓存非常方便。 客户

import { resolvers, typeDefs } from './resolvers';

let cache = new InMemoryCache()
const client = new ApolloClient({
  cache,
  link: new HttpLink({
    uri: 'http://localhost:4000/graphql',
    headers: {
      authorization: localStorage.getItem('token'),
    },
  }),
  typeDefs,
  resolvers,
});

cache.writeData({
  data: {
    isLoggedIn: !!localStorage.getItem('token'),
    cartItems: [],
  },
})

LoginPage

const IS_LOGGED_IN = gql`
  query IsUserLoggedIn {
    isLoggedIn @client
  }
`;

function IsLoggedIn() {
  const { data } = useQuery(IS_LOGGED_IN);
  return data.isLoggedIn ? <Pages /> : <Login />;
}

onLogin

function Login() {
  const { data, refetch } = useQuery(LOGIN_QUERY);
  let viewer = data && data.viewer
  if (viewer){
    localStorage.setItem('token',viewer.token)
  }
  // rest of the stuff
}

onLogout

onLogout={() => {
        client.writeData({ data: { isLoggedIn: false } });
        localStorage.clear();
      }}

有关本地状态管理的更多信息。检出this

希望这会有所帮助!