阿波罗客户端在反应原生的初始重新加载中返回未定义

Posted

技术标签:

【中文标题】阿波罗客户端在反应原生的初始重新加载中返回未定义【英文标题】:apollo client returning undefined in initial reload in react native 【发布时间】:2020-04-29 23:12:37 【问题描述】:

我正在尝试从我的缓存中获取一些数据。在初始重新加载数据道具返回未定义但如果我快速重新加载应用程序(反应本机快速重新加载)数据道具具有我想要的值。我不明白为什么它在初始重新加载时返回未定义。一种情况可能是我在缓存初始化之前调用查询。我已经控制了本地缓存,它显示了值,但查询正在重新调整未定义。

我在 client.js 中的客户端设置

const dev = 
  base_url: BASE_URL
;

const httpLink = createHttpLink(
  uri: dev.base_url
);

const errorLink = onError(( graphQLErrors, networkError, response ) => 
  if (graphQLErrors) 
    // do something with graphql error
    console.log(graphQLErrors);
  
  if (networkError) 
    // do something with network error
    console.log(networkError);
    // console.log('network not available');
  
  if (response) 
    console.log(response);
  
);
const cache = new InMemoryCache();

const setupPersistedCache = async () => 
  const persistor = new CachePersistor(
    cache,
    storage: AsyncStorage
  );

  // Read the current schema version from AsyncStorage.
  const currentVersion = await AsyncStorage.getItem(SCHEMA_VERSION_KEY);

  console.log('currentVersion', currentVersion);

  if (currentVersion && currentVersion === SCHEMA_VERSION) 
    // If the current version matches the latest version,
    // we're good to go and can restore the cache.
    console.log('not migrating cache');
    await persistor.restore();
   else 
    // Otherwise, we'll want to purge the outdated persisted cache
    // and mark ourselves as having updated to the latest version.
    console.log('migrating cache');
    await persistor.purge();
    await AsyncStorage.setItem(SCHEMA_VERSION_KEY, SCHEMA_VERSION);

    cache.writeData(
      data: 
        ...initialState
      
    );

    await persistCache(
      cache,
      storage: AsyncStorage,
      debug: true
    );
  
  // console.log(cache.data);
;

setupPersistedCache();

const link = ApolloLink.from([errorLink, httpLink]);

const client = new ApolloClient(
  defaults: initialState,
  link,
  cache,
  resolvers
);

export default client;

我的 initialState.js

export default 
  language: 'bd'
;

我的 index.js

const AppProvider = () => 
  const [loaded, setLoaded] = useState(false);

  const configureCache = async () => 
    try 
      const cache = new InMemoryCache();
      await persistCache(
        cache,
        storage: AsyncStorage,
        debug: true
      );
      console.log(cache.data);
     catch (error) 
      console.error('Error restoring Apollo cache', error);
    
  ;

  useEffect(() => 
    configureCache()
      .then(() => 
        setLoaded(true);
      )
      .catch(() => 
        setLoaded(false);
      );
  , []);
  useEffect(() => 
    SplashScreen.hide();
  , []);

  return (
    <>
      loaded ? (
        <ApolloProvider client=client>
          <Root />
        </ApolloProvider>
      ) : (
        <View style=
          flex: 1,
          justifyContent: 'center',
          alignItems: 'center'
        
        >
          <TextComponent
            content="Loading"
            size=fonts.fs24
            family=fonts.medium
            color=colors.white
          />
        </View>
      )
    </>
  );
;

AppRegistry.registerComponent(appName, () => AppProvider);

我的查询

export const getLangQuery = gql`
  query getLang 
    language @client
  
`;

我正在尝试在我的根页面中获取这样的数据。

const  loading, error, data  = useQuery(getLangQuery);
  const [setLanguage, result] = useMutation(setLangQuery);

  const language = data;
  console.log(language);

【问题讨论】:

【参考方案1】:

data 最初始终是未定义的,即使结果是从缓存而不是服务器获取的。一旦数据被加载,它就保持在组件状态,因此即使组件重新渲染,也不必再次从缓存中获取数据。快速刷新只会触发重新渲染——它不会重新加载整个应用程序——因此任何组件状态(包括本例中的 data)都会被持久化。

【讨论】:

非常有帮助,谢谢。一些示例通过检查数据的定义直接解构数据。【参考方案2】:

我自己想办法。我多次初始化persistCache。一次在client.js中,一次在index.js中。这就是为什么它表现得很奇怪。现在一切都按预期运行。

【讨论】:

以上是关于阿波罗客户端在反应原生的初始重新加载中返回未定义的主要内容,如果未能解决你的问题,请参考以下文章

@apollo/client 反应钩子 useQuery() 数据未定义

使用阿波罗客户端上传图像时获取网络请求失败反应原生android

反应阿波罗 - 在重新获取之前清除数据对象

如何在反应路由器中调用阿波罗客户端 useQuery?

如何在 x 时间后重新渲染反应(突变阿波罗)

如何在点击时重新加载反应原生地图