react-native
expo 应用程序,在我的机器终端中使用 npm run web
启动应用程序后,使用我手机上的 Expo 应用程序扫描终端中的二维码以启动该应用程序。
以下两种情况在我机器的浏览器上都可以正常工作。使用
onError()
的那个(第二个例子)在我的手机上出现“网络错误”并且没有发出 apollo 客户端 http 请求。第一个例子在我的手机上运行良好。
工作
App.js
:
import AsyncStorage from '@react-native-async-storage/async-storage';
import { customColours as colors } from './src/utils';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationBar } from './src/components';
import { NavigationContainer } from '@react-navigation/native';
import NetworkLogger from 'react-native-network-logger';
import { startNetworkLogging } from 'react-native-network-logger';
import { StatusBar } from 'expo-status-bar';
import { ApolloClient, ApolloLink, ApolloProvider, concat, HttpLink, InMemoryCache } from '@apollo/client';
import { MD3LightTheme as DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
import { HomeScreen, LogInScreen, SignUpScreen } from './src/screens';
import { GRAPHQL_URL, NETWORK_LOGGER } from '@env';
const authMiddleware = new ApolloLink(async (operation, forward) => {
const authToken = await AsyncStorage.getItem('authToken');
operation.setContext(({ headers = {} }) => ({
headers: {
...headers,
authorization: authToken
}
}));
return forward(operation);
});
const httpLink = new HttpLink({ uri: GRAPHQL_URL });
const client = new ApolloClient({
cache: new InMemoryCache(),
link: concat(authMiddleware, httpLink)
});
const networkLoggerIsEnabled = NETWORK_LOGGER === 'true';
const Stack = createNativeStackNavigator();
const theme = {
...DefaultTheme,
colors
};
export default function App() {
networkLoggerIsEnabled && startNetworkLogging();
return (
<ApolloProvider client={client}>
<PaperProvider theme={theme}>
<NavigationContainer>
<Stack.Navigator
screenOptions={{
header: props => <NavigationBar {...props} />
}}
>
<Stack.Screen component={HomeScreen} name="Home" options={{ title: 'Home' }} />
<Stack.Screen component={LogInScreen} name="LogIn" options={{ title: 'Log In'}} />
<Stack.Screen component={SignUpScreen} name='SignUp' options={{ title: 'Sign Up' }} />
</Stack.Navigator>
<StatusBar style="auto" />
{networkLoggerIsEnabled && <NetworkLogger />}
</NavigationContainer>
</PaperProvider>
</ApolloProvider>
);
}
非工作
App.js
:
import AsyncStorage from '@react-native-async-storage/async-storage';
import { customColours as colors } from './src/utils';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { NavigationBar } from './src/components';
import { NavigationContainer } from '@react-navigation/native';
import NetworkLogger from 'react-native-network-logger';
import { onError } from '@apollo/client/link/error';
import { startNetworkLogging } from 'react-native-network-logger';
import { StatusBar } from 'expo-status-bar';
import { ApolloClient, ApolloLink, ApolloProvider, from, HttpLink, InMemoryCache } from '@apollo/client';
import { MD3LightTheme as DefaultTheme, Provider as PaperProvider } from 'react-native-paper';
import { HomeScreen, LogInScreen, SignUpScreen } from './src/screens';
import { GRAPHQL_URL, NETWORK_LOGGER } from '@env';
const authMiddleware = new ApolloLink(async (operation, forward) => {
const authToken = await AsyncStorage.getItem('authToken');
operation.setContext(({ headers = {} }) => ({
headers: {
...headers,
authorization: authToken
}
}));
return forward(operation);
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.forEach(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
)
);
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const httpLink = new HttpLink({ uri: GRAPHQL_URL });
const client = new ApolloClient({
cache: new InMemoryCache(),
link: from([authMiddleware, errorLink, httpLink])
});
const networkLoggerIsEnabled = NETWORK_LOGGER === 'true';
const Stack = createNativeStackNavigator();
const theme = {
...DefaultTheme,
colors
};
export default function App() {
networkLoggerIsEnabled && startNetworkLogging();
return (
<ApolloProvider client={client}>
<PaperProvider theme={theme}>
<NavigationContainer>
<Stack.Navigator
screenOptions={{
header: props => <NavigationBar {...props} />
}}
>
<Stack.Screen component={HomeScreen} name="Home" options={{ title: 'Home' }} />
<Stack.Screen component={LogInScreen} name="LogIn" options={{ title: 'Log In'}} />
<Stack.Screen component={SignUpScreen} name='SignUp' options={{ title: 'Sign Up' }} />
</Stack.Navigator>
<StatusBar style="auto" />
{networkLoggerIsEnabled && <NetworkLogger />}
</NavigationContainer>
</PaperProvider>
</ApolloProvider>
);
}
两者之间的区别在于第二个使用
from()
而不是concat()
并且在链中多了一个link
:errorLink
.
我有使用
from()
如果我想使用两个以上的链接-concat()
仅限于2个链接。
errorLink
文档:https://www.apollographql.com/docs/react/api/link/apollo-link-error
我的
package.json
:
{
"name": "my-wordlist-mobile",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"android": "expo start --android",
"ios": "expo start --ios",
"start": "expo start",
"web": "expo start --web"
},
"dependencies": {
"@apollo/client": "^3.7.11",
"@expo/webpack-config": "^18.0.1",
"@react-native-async-storage/async-storage": "1.17.11",
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
"expo": "~48.0.9",
"expo-status-bar": "~1.4.4",
"graphql": "^15.8.0",
"prop-types": "^15.8.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.71.6",
"react-native-network-logger": "^1.14.1",
"react-native-paper": "^5.6.0",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"react-native-web": "~0.18.10"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"eslint": "^8.37.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-native": "^4.0.0",
"react-native-dotenv": "^3.4.8"
},
"private": true
}