1. 程式人生 > >react-navigation 連續點選多次跳轉

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
歡迎各位看官的批評和指正,共同學習和成長
希望該文章對您有幫助,也希望得到您的鼓勵和支援