React-NativeReact Native开发经验集

react-navigation重复点击多次跳转的解决方案

2018-01-19  本文已影响264人  石小泉

废话

分析问题

经过观察发现,在onPress事件执行后会触发navigation.navigate(...)方法,加载新的页面。
但是当页面加载缓慢时,多余的点击会多次触发该事件,导致页面重复加载
看源码
位置:../node_modules/react-navigation/src/addNavigationHelper.js

......
navigate: (
    routeName: string,
    params?: NavigationParams,
    action?: NavigationNavigateAction
): boolean =>
    navigation.dispatch(
        NavigationActions.navigate({ routeName, params, action })
    ),
.....

显然,页面跳转时,并未对事件进行控制,只要触发,就会加载新的页面

解决方案

既然源码未加控制,我们就手动加上,目前思路有2种

普通版

  1. constructor中初始化一个记录是否等待的state
constructor(props) {
    super(props)
    this.state = {
        waiting: false,//防止多次重复点击
    }
}
  1. 利用this.state.waiting控制TouchableOpacitydisabled属性
<TouchableOpacity
    disabled={this.state.waiting}
    onPress={() => this.repeatClick(this.props.navigation)}
>
    <Text style={{padding: 10, color: 'red'}}>goto detail page</Text>
</TouchableOpacity>
...
repeatClick(navigation){
    this.setState({waiting: true});
    /*-------这中间写你需要实现的逻辑------------*/
    navigation.navigate('Detail')
    /*-------这中间写你需要实现的逻辑------------*/
    setTimeout(()=> {
        this.setState({waiting: false})
    }, 3000);//设置的时间间隔根据实际需要
}
  1. 效果展示


    03.gif

进阶版

  1. 修改源码
    位于:../node_modules/react-navigation/src/addNavigationHelper.js
    此次修改基于"react-navigation": "^1.0.0-beta.27"
    修改后的代码如下:
......
......
export default function<S: {}>(
  navigation: NavigationProp<S>
): NavigationScreenProp<S> {
  /*  ------------此处为添加的代码--------- */
  let debounce = true;//  定义判断变量 
  /*  ------------此处为添加的代码--------- */
  return {
    ...navigation,
    goBack: (key?: ?string): boolean => {
      let actualizedKey: ?string = key;
      if (key === undefined && navigation.state.key) {
        invariant(
          typeof navigation.state.key === 'string',
          'key should be a string'
        );
        actualizedKey = navigation.state.key;
      }
      return navigation.dispatch(
        NavigationActions.back({ key: actualizedKey })
      );
    },
    navigate: (
      routeName: string,
      params?: NavigationParams,
      action?: NavigationNavigateAction
  /*  ------------此处为修改后的的代码--------- */
    ): boolean =>{
      if (debounce) {
        debounce = false;
        navigation.dispatch(
          NavigationActions.navigate({
            routeName,
            params,
            action,
          }),
        );
        setTimeout(
          () => {
            debounce = true;
          },
          5000,
        );
        return true;
      }
      return false;
    },
  /*  ------------此处为修改后的的代码--------- */
......
......

此时onPress事件无需再加控制

<TouchableOpacity
    // disabled={this.state.waiting}
    onPress={() => this.props.navigation.navigate('Detail')}
>
    <Text style={{padding: 10, color: 'red'}}>goto detail page</Text>
</T
  1. 看效果


    03.gif

本人翻译了 react-navigation的官方文档

地址:https://www.reactnavigation.org.cn/,欢迎访问

本文结束,欢迎大家加群共同学习

QQ群:672509442

😊😊😊😊
上一篇下一篇

猜你喜欢

热点阅读