Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止在React native中双击_Javascript_React Native_Touchablehighlight - Fatal编程技术网

Javascript 防止在React native中双击

Javascript 防止在React native中双击,javascript,react-native,touchablehighlight,Javascript,React Native,Touchablehighlight,如何防止用户在React native中两次点击按钮 i、 e.用户不能在可触摸高光上快速点击两次使用属性 import React,{Component}来自'React'; 从“react native”导入{AppRegistry、样式表、视图、按钮}; 导出默认类应用程序扩展组件{ 陈述={ 残疾人士:错,, } 按按钮(){ 这是我的国家({ 残疾人:对,, }); //5秒后启用 设置超时(()=>{ 这是我的国家({ 残疾人士:错,, }); }, 5000) } render(

如何防止用户在React native中两次点击按钮

i、 e.用户不能在可触摸高光上快速点击两次使用属性

import React,{Component}来自'React';
从“react native”导入{AppRegistry、样式表、视图、按钮};
导出默认类应用程序扩展组件{
陈述={
残疾人士:错,,
}
按按钮(){
这是我的国家({
残疾人:对,,
});
//5秒后启用
设置超时(()=>{
这是我的国家({
残疾人士:错,,
});
}, 5000)
}
render(){
返回(
单击此按钮。按按钮()}
title=“了解更多信息”
color=“#841584”
disabled={this.state.disabled}
accessibilityLabel=“了解有关此紫色按钮的详细信息”
/>
);
}
}
//如果使用CreateReact本机应用程序,请跳过此行
AppRegistry.registerComponent('AwesomeProject',()=>App)

使用此HOC扩展可触摸组件,如TouchableHighlight、Button

import debounce from 'lodash.debounce'; // 4.0.8

const withPreventDoubleClick = (WrappedComponent) => {

  class PreventDoubleClick extends React.PureComponent {

    debouncedOnPress = () => {
      this.props.onPress && this.props.onPress();
    }

    onPress = debounce(this.debouncedOnPress, 300, { leading: true, trailing: false });

    render() {
      return <WrappedComponent {...this.props} onPress={this.onPress} />;
    }
  }

  PreventDoubleClick.displayName = `withPreventDoubleClick(${WrappedComponent.displayName ||WrappedComponent.name})`
  return PreventDoubleClick;
}
从“lodash.debounce”导入去盎司;//4.0.8
const withPreventDoubleClick=(WrappedComponent)=>{
类防止双击扩展React.PureComponent{
debouncedOnPress=()=>{
this.props.onPress&&this.props.onPress();
}
onPress=debounce(this.debouncedOnPress,300,{前导:true,尾随:false});
render(){
返回;
}
}
PreventDoubleClick.displayName=`withPreventDoubleClick(${WrappedComponent.displayName | | WrappedComponent.name})`
返回双击;
}
用法

import { Button } from 'react-native';
import withPreventDoubleClick from './withPreventDoubleClick';

const ButtonEx = withPreventDoubleClick(Button);

<ButtonEx onPress={this.onButtonClick} title="Click here" />
从'react native'导入{Button};
使用PreventDoubleClick从“/使用PreventDoubleClick”导入;
const buttonnex=带防止双击(按钮);

您也可以在等待异步操作的同时显示正在加载的gif。只需确保用
async()=>{}
标记您的
onPress
,这样它就可以是
wait
'd了

import React from 'react';
import {View, Button, ActivityIndicator} from 'react-native';

class Btn extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isLoading: false
        }
    }

    async setIsLoading(isLoading) {
        const p = new Promise((resolve) => {
            this.setState({isLoading}, resolve);
        });
        return p;
    }

    render() {
        const {onPress, ...p} = this.props;

        if (this.state.isLoading) {
            return <View style={{marginTop: 2, marginBottom: 2}}>
                <ActivityIndicator
                    size="large"
                />
            </View>;
        }


        return <Button
            {...p}
            onPress={async () => {
                await this.setIsLoading(true);
                await onPress();
                await this.setIsLoading(false);
            }}
        />
    }

}

export default Btn;
从“React”导入React;
从“react native”导入{View,Button,ActivityIndicator};
类Btn扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
孤岛加载:false
}
}
异步设置isLoading(isLoading){
const p=新承诺((解决)=>{
this.setState({isLoading},resolve);
});
返回p;
}
render(){
const{onPress,…p}=this.props;
if(此.state.isLoading){
返回
;
}
返回{
等待此消息。setIsLoading(true);
等待按下按钮();
等待此消息。setIsLoading(false);
}}
/>
}
}
导出默认Btn;

我通过参考上面的答案来使用它。”“已禁用”不必是状态

import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';

class PreventDoubleTap extends Component {
    disabled = false;
    onPress = (...args) => {
        if(this.disabled) return;
        this.disabled = true;
        setTimeout(()=>{
            this.disabled = false;
        }, 500);
        this.props.onPress && this.props.onPress(...args);
    }
}

export class ButtonHighLight extends PreventDoubleTap {
    render() {
        return (
            <TouchableHighlight
                {...this.props}
                onPress={this.onPress}
                underlayColor="#f7f7f7"
            />
        );
    }
}
import React,{Component}来自'React';
从“react native”导入{TouchableHighlight};
类扩展组件{
禁用=错误;
onPress=(…参数)=>{
如果(本.禁用)返回;
this.disabled=true;
设置超时(()=>{
this.disabled=false;
}, 500);
this.props.onPress&&this.props.onPress(…args);
}
}
导出类按钮高亮显示双击{
render(){
返回(
);
}
}

它可以是其他可触摸组件,如TouchableOpacity。

如果使用react导航,则使用此格式导航到其他页面。
this.props.navigation.navigation({key:“any”,routeName:“YourRoute”,params:{param1:value,param2:value}})

StackNavigator将防止具有相同密钥的路由再次被推入堆栈。
如果要将参数传递到另一个屏幕,您可以编写任何唯一的
,并且
参数
属性是可选的。

我有一个使用runAfterInteractions的非常简单的解决方案:

   _GoCategoria(_categoria,_tipo){

            if (loading === false){
                loading = true;
                this.props.navigation.navigate("Categoria", {categoria: _categoria, tipo: _tipo});
            }
             InteractionManager.runAfterInteractions(() => {
                loading = false;
             });

    };

我的包装器组件的实现

import React, { useState, useEffect } from 'react';
import { TouchableHighlight } from 'react-native';

export default ButtonOneTap = ({ onPress, disabled, children, ...props }) => {
    const [isDisabled, toggleDisable] = useState(disabled);
    const [timerId, setTimerId] = useState(null);

    useEffect(() => {
        toggleDisable(disabled);
    },[disabled]);

    useEffect(() => {
        return () => {
            toggleDisable(disabled);
            clearTimeout(timerId);
        }
    })


    const handleOnPress = () => {
        toggleDisable(true);
        onPress();
        setTimerId(setTimeout(() => {
            toggleDisable(false)
        }, 1000))
    }
    return (
        <TouchableHighlight onPress={handleOnPress} {...props} disabled={isDisabled} >
            {children}
        </TouchableHighlight>
    )
}
import React,{useState,useffect}来自“React”;
从“react native”导入{TouchableHighlight};
导出默认按钮nonetap=({onPress,disabled,children,…props})=>{
const[isDisabled,toggleDisable]=useState(disabled);
const[timerId,setTimerId]=useState(null);
useffect(()=>{
切换禁用(禁用);
},[残疾];
useffect(()=>{
return()=>{
切换禁用(禁用);
清除超时(timerId);
}
})
康斯特·汉德莱昂出版社=()=>{
切换禁用(true);
onPress();
setTimerId(setTimeout(()=>{
切换禁用(错误)
}, 1000))
}
返回(
{儿童}
)
}

同意公认的答案,但方法非常简单,我们可以使用以下方法

import debounce from 'lodash/debounce';

    componentDidMount() {

       this.onPressMethod= debounce(this.onPressMethod.bind(this), 500);
  }

onPressMethod=()=> {
    //what you actually want on button press
}

 render() {
    return (
        <Button
            onPress={() => this.onPressMethod()}
            title="Your Button Name"
          />
    );
  }
从“lodash/debounce”导入去盎司;
componentDidMount(){
this.onPressMethod=debounce(this.onPressMethod.bind(this),500);
}
onPressMethod=()=>{
//按一下按钮你到底想要什么
}
render(){
返回(
this.onPressMethod()}
title=“您的按钮名称”
/>
);
}

公认的解决方案效果很好,但它强制您包装整个组件并导入lodash以实现所需的行为。 我编写了一个定制的React钩子,它只允许包装回调:

useTimeBlockedCallback.js

import { useRef } from 'react'

export default (callback, timeBlocked = 1000) => {
  const isBlockedRef = useRef(false)
  const unblockTimeout = useRef(false)

  return (...callbackArgs) => {
    if (!isBlockedRef.current) {
      callback(...callbackArgs)
    }
    clearTimeout(unblockTimeout.current)
    unblockTimeout.current = setTimeout(() => isBlockedRef.current = false, timeBlocked)
    isBlockedRef.current = true
  }
}
用法:

yourComponent.js

import React from 'react'
import { View, Text } from 'react-native'
import useTimeBlockedCallback from '../hooks/useTimeBlockedCallback'

export default () => {
  const callbackWithNoArgs = useTimeBlockedCallback(() => {
    console.log('Do stuff here, like opening a new scene for instance.')
  })
  const callbackWithArgs = useTimeBlockedCallback((text) => {
    console.log(text + ' will be logged once every 1000ms tops')
  })

  return (
    <View>
      <Text onPress={callbackWithNoArgs}>Touch me without double tap</Text>
      <Text onPress={() => callbackWithArgs('Hello world')}>Log hello world</Text>
    </View>
  )
}
从“React”导入React
从“react native”导入{View,Text}
从“../hooks/useTimeBlockedCallback”导入useTimeBlockedCallback
导出默认值()=>{
const callbackWithNoArgs=useTimeBlockedCallback(()=>{
log('在这里做一些事情,比如打开一个新场景')
})
const callbackWithArgs=useTimeBlockedCallback((文本)=>{
console.log(文本+'将每1000ms记录一次')
})
返回(
不要轻触我
callb