React Native Router Flux中如何覆盖后退按钮?

5
我正在我的React Native应用程序中使用React Native Router Flux。我想要覆盖返回按钮按下事件,因为我想在返回之前添加确认弹出窗口。我已经搜索了很多链接,但是所有的链接都是针对Android硬件返回按钮的覆盖。我不仅想覆盖硬件返回按钮,还想覆盖导航栏中的返回按钮按下事件(适用于Android和iOS)。请帮我解决这个问题。
编辑:我找到了一种通过在我的场景中添加两个属性back和onBack来覆盖后退事件的方法。但现在的问题是我希望这个后退事件是有条件的。我将一个布尔型prop edit传递给这个场景。如果edit为true,那么只有我想要覆盖后退事件,否则我只想要默认的。那么如何使用传递给该场景的props更改我的Router.js中的Scene参数?
sudo代码
if(edit){
   openConfirmationDialog();
} else {
   Actions.pop();
}
4个回答

5
对我来说,@Raj Suvariya提供的解决方案是有效的,但只有在我为想要自定义“返回”操作的场景(例如Raj示例中的“主页”场景)添加了一个“renderBackButton”回调后才有效果。因此,将以下内容添加到场景的定义中:
renderBackButton={()=>{}}

在导航到页面时,与 Raj 的上面的答案相同,添加了这个内容:

Actions.Home({onBack: () => console.log('custom back callback') });

4

React Native | react-native-router-flux | Redux | Android 返回按钮监听器,当使用React Native时处理Android返回按键。

// below code works with Android + react native + react-native-router-flux
// this is final index.js file code from where control whole app navigation
import { BackHandler, ToastAndroid } from 'react-native';
import React,{Component} from 'react';
import { Router, Scene, Actions } from 'react-native-router-flux';
import { Provider } from 'react-redux';
// as per your compoenents import them accordingly
import Home from './home';
import OtherScreen from './OtherScreen';
//variable 
var backButtonPressedOnceToExit = false;

export default class App extends Component {

  componentWillMount(){
    BackHandler.addEventListener('hardwareBackPress', this.onBackPress.bind(this));
  }

  componentWillUnmount(){
    BackHandler.removeEventListener('hardwareBackPress', this.onBackPress.bind(this));
    }

  onBackPress() {
        if (backButtonPressedOnceToExit) {
            BackAndroid.exitApp();
        } else {
            if (Actions.currentScene !== 'Home') {
                Actions.pop();
                return true;
            } else {
                backButtonPressedOnceToExit = true;
                ToastAndroid.show("Press Back Button again to exit",ToastAndroid.SHORT);
                //setting timeout is optional
                setTimeout( () => { backButtonPressedOnceToExit = false }, 2000);
                return true;
            }
        }
    }

    render() {
      return(
        <Provider store={store}>
          <Router backAndroidHandler={this.onBackPress} >
            <Scene key="root" }>
              <Scene key="Home" component={Home} initial={true}  />
              <Scene key="OtherScreen" component={OtherScreen}  />
            </Scene>
          </Router>
        </Provider>
      );
    }
}

AppRegistry.registerComponent('YourAppNameAccordingToPackageJSON', () => App);

我使用了和这个样例一样的代码。 - Lavaraju
请从资产中删除android.bundle.meta并尝试重新构建。 - Abhishek Garg

2

好的!我找到了它的方法。

无论我从哪里打开这个场景,我都可以像这样传递onBack回调:Actions.Home({onBack: () => console.log('自定义返回回调') });

这样,我每次打开该场景时都可以提供动态的返回回调。


你找到任何解决方案可以访问被调用的操作的字段或属性以便检查某些条件吗? - Allloush
如何知道用户是否从顶部栏按下返回按钮?从组件中? - user3804063

0

我也遇到了这个问题,但是我没有像Raj的帖子中那样在props中添加onBack。如果你有很多地方需要覆盖,添加onBack prop会非常麻烦。我的做法是覆盖RNRF的默认onBackPress函数。

//App.js

    <Router
        scenes={scenes}
        createReducer={reducerCreate}
        getSceneStyle={getSceneStyle}
        backAndroidHandler={() => {
            let cs = Actions.currentScene;
            if (cs === 'sc1' || cs === 'sc2') {

            } else {
                // default, pop back
                Actions.pop();
            }
            return true;
        }}
    />

    //component1.js, "component1" is a key in scenes registered.

    handleBackAction = () => {
        if (Actions.currentScene === "component1") {
            // do something you want and return true to intercept back event.
            return true;
        }
        return false;
    }
    componentDidMount() {
        this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackAction);
    }

    componentWillUnmount() {
        this.backHandler.remove();
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接