我正在学习 React Native 中的导航,并且不知道如何有条件地使用一个后退按钮。 想要的行为是这样的 - 如果用户在屏幕之间导航,他可以按“返回”按钮,但如果其中一个屏幕包含 WebView 并且他已经访问了那里的几个页面,则用户将首先返回此 WebView 页面,然后返回屏幕。希望这是有道理的。 类似这样的东西:屏幕 A <- Screen B <- Screen C with WebView <- Webview Page 1 <- Webview Page 2
应用程序屏幕
import React from 'react';
import {Pressable, StyleSheet, Text} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './src/screens/HomeScreen';
import WebViewScreen from './src/screens/WebViewScreen';
import ParamsScreen from './src/screens/ParamsScreen';
const Stack = createNativeStackNavigator();
function App(): React.JSX.Element {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName="Home"
screenOptions={
({navigation}) => {}
}>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{title: 'Customized Header Home'}}
/>
<Stack.Screen
name="WebView Screen"
component={WebViewScreen}
options={({navigation, route}) => ({
title: 'Webview',
headerLeft: () => (
<Pressable onPress={() => navigation.goBack()}>
<Text style={{color: 'blue'}}>Go Back within Screens</Text>
</Pressable>
),
})}
/>
<Stack.Screen name="Params Screen" component={ParamsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({});
export default App;
WebViewScreen
import {StyleSheet, Text, View, ActivityIndicator, Button} from 'react-native';
import React, {useRef, useState} from 'react';
import {WebView} from 'react-native-webview';
const WebViewScreen = ({navigation, route}) => {
const webViewRef = useRef<WebView>(null);
return (
<>
<View style={{flex: 0, alignItems: 'center', justifyContent: 'center'}}>
<Text>WebView Screen</Text>
<Button
title="Go Back within WebView"
onPress={() => webViewRef.current?.goBack()}
/>
</View>
<WebView
source={{uri: 'https://google.com'}}
startInLoadingState
ref={webViewRef}
renderLoading={() => (
<View style={{flex: 1, alignItems: 'center'}}>
<ActivityIndicator size="large" />
</View>
)}
allowsBackForwardNavigationGestures
onNavigationStateChange={navState => {}}
/>
</>
);
};
export default WebViewScreen;
const styles = StyleSheet.create({});
目前我已经设法拥有两个独立的工作按钮,但如果在标题中拥有一个后退按钮会更好。 我正在使用 Screen options 和 onNavigationStateChange 参数,但有点迷失在那里。
我想我需要某种像这样的功能:
const goBack = () => {
if (webViewRef.current) {
webViewRef.current.goBack();
} else {
navigation.goBack();
}
};
但不确定如何将其与 Stack.Navigator 集成
您可以通过在
headerLeft
中组合使用 onNavigationStateChange
和 WebViewScreen
来实现所需的行为。这是 WebViewScreen
的修改版本,应该可以帮助您实现组合后退功能:
import { StyleSheet, Text, View, ActivityIndicator, Button } from 'react-native';
import React, { useRef } from 'react';
import { WebView } from 'react-native-webview';
const WebViewScreen = ({ navigation, route }) => {
const webViewRef = useRef();
const handleNavigationStateChange = (navState) => {
// Check if WebView can go back
const canGoBack = navState.canGoBack;
// Update the header left button based on WebView navigation
navigation.setOptions({
headerLeft: () => (
<View style={{ marginLeft: 10 }}>
<Button
onPress={() => {
if (canGoBack) {
// If WebView can go back, go back in WebView
webViewRef.current.goBack();
} else {
// If WebView cannot go back, go back in the navigation stack
navigation.goBack();
}
}}
title="Go Back"
color="blue"
/>
</View>
),
});
};
return (
<>
<View style={{ flex: 0, alignItems: 'center', justifyContent: 'center' }}>
<Text>WebView Screen</Text>
</View>
<WebView
source={{ uri: 'https://google.com' }}
startInLoadingState
ref={webViewRef}
renderLoading={() => (
<View style={{ flex: 1, alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
)}
allowsBackForwardNavigationGestures
onNavigationStateChange={handleNavigationStateChange}
/>
</>
);
};
export default WebViewScreen;
const styles = StyleSheet.create({});
在此代码中,
handleNavigationStateChange
函数检查WebView是否可以返回(canGoBack
)。然后它会相应地更新 headerLeft
按钮。如果WebView可以返回,按钮将触发webViewRef.current.goBack()
,否则,将触发导航堆栈中的navigation.goBack()
返回。
这样,标题中就有一个“返回”按钮,可以处理 WebView 和屏幕导航。