React Native(Expo)渲染前获取IP地址传入Apollo Client的实现问题
实现方案
异步获取IP的操作无法阻塞顶层代码的同步执行,因此我们可以把Apollo Client的初始化逻辑移到根组件内部,配合状态管理和加载状态,确保IP获取完成后再初始化客户端、渲染应用内容。
完整修改代码
import React, { useState, useEffect } from 'react'; import { ApolloClient, InMemoryCache, createHttpLink, ApolloProvider, setContext } from '@apollo/client'; import * as Network from 'expo-network'; import { ActivityIndicator, View } from 'react-native'; // 用于加载状态展示 // 获取本地IP方法 async function getLocalIPAddress() { const ipAddress = await Network.getIpAddressAsync(); return ipAddress; } export default () => { const [client, setClient] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const initApolloClient = async () => { try { // 优先获取本地IP const localIP = await getLocalIPAddress(); // 动态创建httpLink const httpLink = createHttpLink({ uri: `http://${localIP}:5000/graphql`, }); // 原有authLink逻辑保持不变 const authLink = setContext(async (_, { headers }) => { // 此处保留你原有的headers处理逻辑 return { headers: { ...headers, // 自定义header配置 } } }); // 完成Apollo Client初始化 const apolloClient = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache() }); setClient(apolloClient); } catch (err) { // 可自行添加IP获取或初始化失败的异常处理逻辑 console.error('客户端初始化失败', err); } finally { setLoading(false); } }; initApolloClient(); }, []); // 加载阶段展示加载态,避免ApolloProvider接收到空实例 if (loading) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } // 初始化完成后渲染正式应用内容 return ( <ApolloProvider client={client}> <SomeModule> </SomeModule> </ApolloProvider> ); };
补充说明
如果需要更流畅的启动体验,可以接入Expo启动屏组件,在初始化完成后再隐藏启动屏,替换上述的简单加载指示器即可。该方案能确保所有Apollo相关请求都在客户端初始化完成后发起,不会出现请求发往旧静态地址的问题。
内容的提问来源于stack exchange,提问作者Tyler Hervey
相关产品推荐
相关产品推荐

