react-navigation 连续点击多次跳转

问题描述,关于react-navigation 导航库在快速连续点击的时候,叶面会发生多次跳转,初次遇到这个坑爹的问题时,一脸懵逼,看过源码,几经折腾终于弄明白了是咋会儿事儿

问题出现的原因:
node_modules/react-navigation/src/NavigationActions.js 下的部分代码

// 罪魁祸首是因没有针对该事件做相应的延迟处理,用源码可以看到,每次点击都会触发该事件,只要路由构长,这种bug必然
const navigate = payload => {
  const action = {
    type: NAVIGATE,
    routeName: payload.routeName,
  };
  if (payload.params) {
    action.params = payload.params;
  }
  if (payload.action) {
    action.action = payload.action;
  }
  if (payload.key) {
    action.key = payload.key;
  }
  return action;
};

直接解决方案:

  • 直接改源码,但是不易维护(不建议)
  • 自行封装进行控制

高阶组件统一封装,代码如下:

HOCTouchable.js
/** react 组建的引用 */
import React, { Component } from "react";
import { TouchableWithoutFeedback } from "react-native";

/** 第三方依赖库的引用 */
import PropTypes from "prop-types";

// 高阶组件的封装,为了满足所有类型以及点击事件
export default function HOCTouchable(TagComponent) {
  class CTouchable extends Component {
    static propTypes = {
      disabled: PropTypes.bool,
      onPress: PropTypes.func
    };
    static defaultProps = {
      disabled: false,
      onPress: null
    };

    constructor(props) {
      super(props);
      this.timer = null;
      this.isJump = true;
    }

    /** 判断是否允许进行页面的跳转 */
    _isAllowToJump = () => {
      if (this.isJump) {
        this._changeJump();
        return true;
      } else {
        return false;
      }
    };

    /** 通过定时器来控制页面的跳转,防止react-navigation连续快速点击会导致页面多次跳转 */
    _changeJump = () => {
      this.isJump = false;
      this.timer = setTimeout(() => {
        this.isJump = true;
        clearTimeout(this.timer);
        this.timer = null;
      }, 500);
    };

    _onPress = () => {
      const { handle } = this.props;
      this._isAllowToJump() && handle instanceof Function && handle();
    };

    render() {
      return <TagComponent {...this.props} onPress={this._onPress} />;
    }
  }
  return CTouchable;
}

用法如下

xxx.js
import React, {Component} from "react";
import {TouchableWithoutFeedback,Linking, TouchableHighlight, TouchableOpacity} from "react-native";
import HOCTouchable from 'xx/CTouchable';  // 根据自己也页面的相对路径进行引用
const CTouchableWithoutFeedback = HOCTouchable(TouchableWithoutFeedback)  
// 根据实际开发,根据高阶组件生成经过封装的新的点击按钮

// 简单的使用介绍到这里
render () {
	return (
		  <CTouchableWithoutFeedback
              handle={() => {
                this.props.navigation.navigate('AccountInfo', this.state.userInfo)
              }}>
              <View style={{
                width: 116, height: 116,
                position: 'relative',
                marginLeft: 23,
                justifyContent: 'flex-end',
              }}>
                <ImageBackground
                  fadeDuration={0}
                  style={[styles.avatarbg, styles.imgPos]}
                  source={require('../../images/common/common_shadow_abatar.png')}>
                  <View style={styles.avatarbg_ar_wrap}>
                    <Image
                      fadeDuration={0}
                      style={[styles.avatarbg_ar, {borderRadius: 50}]}
                      source={headPicture ? {uri: headPicture} : require('../../images/me/index_icon_bixia.png')}/>
                  </View>
                </ImageBackground>

                <ImageBackground
                  fadeDuration={0}
                  style={[styles.imgPos, styles.avatarbg,]}
                  source={require('../../images/me/me_img_headmask.png')}
                >
                </ImageBackground>
              </View>
            </CTouchableWithoutFeedback>
	)
}

更多的干货请点击这里
react-native 实战项目demo
欢迎各位看官的批评和指正,共同学习和成长
希望该文章对您有帮助,也希望得到您的鼓励和支持

猜你喜欢

转载自blog.csdn.net/woleigequshawanyier/article/details/85267662
今日推荐