React 项目控制 Android 返回键进行页面跳转

需求

最近开发 React 项目中遇到了这么一个需求

比如项目中有页面 A、页面 B、页面 C、页面 D,前端使用 react-router 进行正常路由跳转,路由为:A -> B -> C -> D。当页面到 D 的时候点击返回(无论是 HeaderBar 还是实体返回按钮)要返回到页面 A,且无论什么情况下在页面 A 点击返回都要退出 H5 页面返回 Native 界面。

关键点

由于 HeaderBar 的返回按钮行为由 native 端通过 JSBridge 提供了监听事件,所以很简单。

window.back = () => {
  const pathname = window.location.pathname;
  if (pathname.indexOf('/A') > -1) {
    jsbridge.pop(); // jsbridge 的退出 H5 事件
  } else if (pathname.indexOf('/D') > -1) {
    this.props.history.push({
      pathname: 'A'
    });
  } else {
    this.props.history.goBack();
  }
}

但是 Android 的物理返回按钮走得是正常的 history 返回上一页流程。

解决 Android 物理返回键

查了不少监听 Android 返回键行为监听的方法,发现都是监听 popstate 方法来做的。

页面A

componentDidMount() {
    window.addEventListener('popstate', this.goBack);
    window.history.pushState(null, '', '');
  }

  componentWillUnmount() {
    window.removeEventListener('popstate', this.goBack);
  }

  goBack = () => {
    jsbridge.pop(); // jsbridge 的退出 H5 事件
  }

页面D

  componentDidMount() {
    window.addEventListener('popstate', this.goIndex);
    window.history.pushState(null, '', '');
  }

  componentWillUnmount() {
    window.removeEventListener('popstate', this.goIndex);
  }

  // 去页面 A
  goIndex = () => {
    this.props.history.push({
      pathname: 'A'
    });
  };

简单解释下,当前页面是 A,点击返回则直接调用 native 的退出 H5 接口行为;当页面在 D,点击返回则跳转到页面 A。这样就避免了 history 中的复杂路由处理了,简单粗暴。

另外注意到 window.history.pushState(null, '', ''); 这段代码,为什么要推一个空的页面呢?
因为 popstate 事件的触发机制是:当 A 监听了 popstate 事件,那么从 B 返回到 A 时会触发 A 的 popstate 事件。所以监听当前页的方法就是往 window.history 中再推一个空值。这样就能在返回事件中触发 popstate 事件。

页面加载时Chrome和Safari通常会触发(emit )popstate事件

参考资料

  • React Router
  • popstate - Web API 接口 | MDN

你可能感兴趣的:(React 项目控制 Android 返回键进行页面跳转)