GVKun编程网logo

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

14

在本文中,我们将给您介绍关于react-navigation重复点击多次跳转的解决方案的详细内容,并且为您解答react防止重复点击的相关问题,此外,我们还将为您提供关于@react-navigati

在本文中,我们将给您介绍关于react-navigation重复点击多次跳转的解决方案的详细内容,并且为您解答react 防止重复点击的相关问题,此外,我们还将为您提供关于@ react-navigation / native和@ react-navigation / stack读取整个堆栈、@react-navigation/native 和 @react-navigation/stack 应该是我模块的 peerDependencies 或依赖项吗?、initialProps被React-Navigation的navigation属性覆盖解决方案、javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)的知识。

本文目录一览:

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

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

废话

  • 在react-native@0.44版本之后,官方废弃了之前的导航Navigator,用react-navigation 替代
  • react-natvigation于2017年1月份开源,在3个月时间内,GitHub上star数达4000+,备受推崇,由于其性能体验堪比原生,而且使用方便,最后被FB钦点为“御用导航”
  • 但是在使用过程中还是发现了一个问题:在触发页面跳转的View上 重复、快速点击时,即将被加载的页面会多次被加载(感谢测试小姐姐丧心病狂的操作),症状如下图

分析问题

经过观察发现,在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种
- 普通版onPress事件处控制,第一次点击后,加上延时,禁止之后的点击操作,但是需要每个点击事件都添加
- 进阶版 直接修改源码,给navigation.dispatch加延时,一劳永逸

普通版

  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. 效果展示

进阶版

  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. 看效果

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

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

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

QQ群:672509442

@ react-navigation / native和@ react-navigation / stack读取整个堆栈

@ react-navigation / native和@ react-navigation / stack读取整个堆栈

您可以使用如下所示的useNavigationState钩子来获取当前状态

https://reactnavigation.org/docs/use-navigation-state/

import {useNavigationState} from '@react-navigation/native';

const state = useNavigationState((state) => state);

alert(JSON.stringify(state.routes));

这将在路线中显示屏幕

@react-navigation/native 和 @react-navigation/stack 应该是我模块的 peerDependencies 或依赖项吗?

@react-navigation/native 和 @react-navigation/stack 应该是我模块的 peerDependencies 或依赖项吗?

如何解决@react-navigation/native 和 @react-navigation/stack 应该是我模块的 peerDependencies 或依赖项吗??

我正在编写一个使用以下依赖项的模块:

{
    "@react-native-community/masked-view": "^0.1.10","@react-navigation/native": "^5.9.4","@react-navigation/stack": "^5.14.4","@react-native-community/masked-view": "^0.1.10","env-cmd": "^10.1.0","firebase": "^8.4.1","react-native-gesture-handler": "^1.10.3","react-native-reanimated": "^2.1.0","react-native-safe-area-context": "^3.2.0","react-native-screens": "^3.1.1"
}

我知道存储单例状态的依赖项不应该在 dependencies 中,而应该在 devDependenciespeerDependencies 中。

我不认为 react-navigation 是一个单独的依赖项,我们可以创建导航的 ref。

可以在我的分布式模块 dependencies 中将这些依赖项用作 package.json 吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

initialProps被React-Navigation的navigation属性覆盖解决方案

initialProps被React-Navigation的navigation属性覆盖解决方案

怎么开场对我来说一个是个很纠结的问题,Emmm这应该算个好开场。
最近在做一个RN的app端调试工具,在把它嵌入原生app中的时候遇到了一个问题,RN组件里面接受不到原生传过来的initialProps?!


先po一下问题原因和答案,看官们有兴趣的话可以再看看下面的废话。
问题原因:首先看下我们一般怎么写,

const AppWithDebug = createStackNavigator({
  Home: {
    screen: App
  },
  ...debugRoute
});

AppRegistry.registerComponent(appName, () => AppWithDebug);

一般情况下,我们会把createStackNavigator生成的对象,作为AppRegistry.registerComponent的入口文件,这个时候react-navigation在接收到initialProps之后并不会向下传递,而是只向下传递自身的navigation对象内容因此这个时候我们在组件中就拿不到原生传过来的initialProps内容了。
解决方案:隔离入口,不再使用createStackNavigator的结果去作为AppRegistry.registerComponent的入口,如

const AppWithDebug = createStackNavigator({
  Home: {
    screen: App
  },
  ...debugRoute
});

class AppEntry extends Component {
    render() {
      return <AppWithDebug screenProps={ this.props }/>
  }
};

AppRegistry.registerComponent(appName, () => AppEntry);

react-navigation不再处于项目入口的位置,入口处由一个包含了导航组件的组件代替。此时我们在AppEntry组件中就可以直接通过this.props拿到initialProps的值了,再通过screenProps向下传递即可,AppWithDebug中可以通过this.props.screenProps获取initialProps的相关内容。
~~问题解决~~以下是爬坑过程~~


碰到这个问题第一反应,什么鬼?官方文档是这么介绍的啊,

这里的initialProperties注入了一些演示用的数据。在 React Native 的根组件中,我们可以使用this.props来获取到这些数据。--RN中文网
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
      moduleName: @"RNHighScores"
initialProperties:
 @{
   @"scores" : @[
     @{
       @"name" : @"Alex",
       @"value": @"42"
      },
     @{
       @"name" : @"Joel",
       @"value": @"10"
     }
   ]
 }
   launchOptions: nil];
注:请忽略我的强行缩进,节省点大家横向拖动的时间

文档写的明明白白,难道我是个傻子?你传过来,我直接this.props.xxx,一点毛病没有啊,为啥拿不到?在去原生同学那里一看他们的demo获取正常。。。

这个时候就准备在自己的项目上开始各种骚操作尝试一下,但是没等我大展拳脚就发现自己可能掉进react-navigation的坑里了,因为最开始去获取initialProps的时候打印了一下this.props对象,发现只有navigation一个子属性,于是就把导航去掉试了一下发现initialProps的属性居然就蹦出来了,这个时候基本就可以确定问题出在react-navigation上了。
这个时候去react-navigation的github官网上查一下issue,就发现了这个

看样子楼主遇到了一样的问题,并且真的是一步一步的证明了react-navigation在这个上面的bug,但第一次看了一圈没找到答案,直到第二次才找到答案

看到这里,真的是恍然大悟,你应该也明白了吧~其实就是隔离入口

经常看到结论,会恍然大悟“哦 原来就这样啊 这么简单”。
其实很多时候答案并不复杂,我们所或缺的是思考问题的方法,之所以写答案下面的这些”废话“,也是最近特别烦躁,经常会被问题卡住并且变得更烦躁,想给自己提个醒,让自己静一静。
目前的开发工作,除非是原创性的工作,一般情况下你遇到的问题都是别人遇到过的,只要去找,可能会很长时间,但终归还是可以解决的,github的issue是个找答案的好地方,耐心寻找。
烦躁并不能解决问题,只会扰乱你的思路,所以不要被情绪左右你的理智。
~加油 你是最胖的~

javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)

javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)

我想在特定超时后将启动画面导航到下一个屏幕.启动画面有一个动画,在Airbnb Lottie的帮助下为React Native完成.

splashscreen代码如下:

import React from "react";
import { Animated,Easing } from "react-native";
import LottieView from "lottie-react-native";
import { NavigationActions } from "react-navigation";

export default class SplashScreen extends React.Component {
  static navigationoptions = {
    header: null
  };

  constructor() {
    super();
    this.state = {
      progress: new Animated.Value(0),}
  }

  componentDidMount() {
    setTimeout(() => {
      this.navigatetoWalkthrough()
    },3500);
    
    Animated.timing(this.state.progress,{
      tovalue: 1,duration: 3000,easing: Easing.linear,}).start();
  }

  navigatetoWalkthrough = () => {
    const navigateAction = NavigationActions.reset({
      index: 0,actions: [NavigationActions.navigate({ routeName: "Walkthrough" })],});

    this.props.navigation.dispatch(navigateAction);
  }

  render() {
    return(
      <LottieView 
      source={require("../assets/splash/SplashScreenAnimation.json")}
      progress={this.state.progress}
      />
    );
  }
}

我运行应用程序后出现错误:

undefined is not a function (evaluating'_reactNavigation.NavigationActions.reset')

Main.js文件如下所示:

import React from "react";
import { View,Text } from "react-native";
import { createStackNavigator } from "react-navigation";

import SplashScreen from "./screens/SplashScreen";
import Walkthrough from "./screens/Walkthrough";

const Routes = createStackNavigator({
  Home: {
    screen: SplashScreen
  },Walkthrough: {
    screen: Walkthrough
  }
});

export default class Main extends React.Component {
  render() {
    return <Routes />;
  }
}

任何帮助/反馈?

解决方法

从NavigationActions中删除了重置操作,并且在反应导航的v2中有特定于StackNavigator的 StackActions.

StackActions is an object containing methods for generating actions
specific to stack-based navigators. Its methods expand upon the
actions available in NavigationActions.

The following actions are supported:

Reset – Replace current state with a new state

Replace – Replace a route at a given key with another route

Push – Add a route on the top of the stack,and navigate forward to it

Pop – Navigate back to prevIoUs routes

PopToTop – Navigate to the top route of the stack,dismissing all other routes

今天关于react-navigation重复点击多次跳转的解决方案react 防止重复点击的分享就到这里,希望大家有所收获,若想了解更多关于@ react-navigation / native和@ react-navigation / stack读取整个堆栈、@react-navigation/native 和 @react-navigation/stack 应该是我模块的 peerDependencies 或依赖项吗?、initialProps被React-Navigation的navigation属性覆盖解决方案、javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)等相关知识,可以在本站进行查询。

本文标签: