繁体   English   中英

React Native Navigation 覆盖 Stack Navigator 中 header 后退按钮的 goBack()

[英]React Native Navigation override goBack() of header back button in Stack Navigator

我想在本地自定义堆栈导航器中默认后退按钮的行为到一个屏幕。

在假设堆栈上有screen1 | screen2的细节中,一旦按下按钮,我想将一些道具从screen2传递到screen1。

我花了很多时间阅读 React 导航文档,在互联网上搜索和编码,但我无法做到这一点。

来自文档

在某些情况下,您可能希望通过上述选项自定义后退按钮,在这种情况下,您可以将 headerLeft 选项设置为将呈现的 React Element 我知道问题与 goBack( ) headerRight 组件的 function。

我想用类似 navigation.navigate("previousScreen",{{..props}}) 的方式覆盖与 headerLeft 后退按钮相关的默认 function goBack()。

而且(这非常重要,。)我想在本地使用此行为到特定屏幕,而不是全局。

我已经尝试过这样的事情,但不起作用。

 export default function App(){
 return(
 <NavigationContainer>
  <Stack.Navigator>
    <Stack.Screen name="FirstScreen" component={FirstScreen}/>
    <Stack.Screen name="SecondScreen" component={SecondScreen} options={{headerLeft: () => (
        <HeaderBackButton
          onPress={() =>navigation.navigate("FirstScreen",{//stuff//})}
          title="Info"
          color="#fff"
        />
      ),}}/>
  </Stack.Navigator>
</NavigationContainer>
 )}

如果您使用的是反应导航 v5,您可以使用以下命令设置特定屏幕的行为:

import { HeaderBackButton } from '@react-navigation/stack';

...
options={{
          headerLeft: (props) => (
            <HeaderBackButton
              {...props}
              onPress={() => {
                navigation.navigate('screenName');
              }}
            />
          ),
        }}
...

您也可以改为使用 screenOptions={{}} 设置为堆栈级别。

“导航”和“路线”也可以在屏幕道具上使用。

options={({ navigation, route }) => ({headerLeft: ...})

安装组件后,注册后退按钮按下监听器

componentDidMount() {
    BackHandler.addEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
}

componentWillUnmount() {
    BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPressAndroid)
}

然后在function中,可以查看和处理action,例如:

onBackButtonPressAndroid = () => {
    // Check if the current screen is focused or a subscreen is perhaps
    if (this.props.navigation.isFocused()) {
        if (someCondition) {
            // Do a navigation to a custom screen, pass props here if needed
            this.props.navigation.navigate('search')
            return true
            // Return true if you want to tell react navigation you've handled the back press
        }
        else if (this.state.offsetTop > 10) {
            // Ex. for scrolling to top
            this.scrollToTop()
            this.setState({
                offsetTop: 0,
            })
            return true
        }
    }
    // Return false if you want to tell react navigation you didn't handle the back press
    return false
}

尝试将navigationOptions传递到特定屏幕:

export default function App(){
 return(
 <NavigationContainer>
  <Stack.Navigator>
    <Stack.Screen name="FirstScreen" component={FirstScreen}/>
    <Stack.Screen name="SecondScreen" component={SecondScreen}
       navigationOptions: ({ navigation }) => ({ headerLeft: (<HeaderBackButton onPress={() => {}}/>)
    })}}/>
  </Stack.Navigator>
</NavigationContainer>
 )}

您可以在navigation中指定它。 或者在Second screen ,试试这个:

class SecondScreen extends React.Component {
  static navigationOptions = {
    headerLeft: (
      <Button
        onPress={() => alert('This is a back button!')}
        title="Title"
        color="#fff"
      />
    ),
  };
}

对于 react-navigation v6,您可以在 useEffect 中使用 setOptions

import { HeaderBackButton } from '@react-navigation/elements';

...

const ChatScreen = ({navigation}) => {

     useEffect( () => {
            navigation.setOptions({ headerShown: true,
                                    headerLeft: (props) => (
                                        <HeaderBackButton
                                            {...props}
                                            onPress={() => {
                                                navigation.navigate('MyScreen');
                                            }}
                                        />
                                    )
                                  });
        } ); 
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM