web-dev-qa-db-fra.com

Empêcher le double tap en React natif

Comment empêcher un utilisateur d'appuyer deux fois sur un bouton dans React native?

c'est-à-dire qu'un utilisateur ne doit pas pouvoir appuyer deux fois rapidement sur une mise en évidence tactile

5
gourav.singhal

https://snack.expo.io/@patwoz/withpreventdoubleclick

Utilisez ce HOC pour étendre les composants tactiles tels que 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;
}

Utilisation

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

const ButtonEx = withPreventDoubleClick(Button);

<ButtonEx onPress={this.onButtonClick} title="Click here" />
14
Patrick Wozniak

Utilisez la propriété Button.disabled

import React, { Component } from 'react';
import { AppRegistry, StyleSheet, View, Button } from 'react-native';

export default class App extends Component {
  
  state={
    disabled:false,
  }
  
  pressButton() {
    this.setState({
      disabled: true,
    });
    
    // enable after 5 second
    setTimeout(()=>{
       this.setState({
        disabled: false,
      });
    }, 5000)
  }
  
  render() {
    return (
        <Button
            onPress={() => this.pressButton()}
            title="Learn More"
            color="#841584"
            disabled={this.state.disabled}
            accessibilityLabel="Learn more about this purple button"
          />
    );
  }
}



// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => App);

5

Je l'utilise en me référant à la réponse ci-dessus. «désactivé» ne doit pas nécessairement être un État.

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"
            />
        );
    }
}

Il peut s'agir d'un autre composant tactile tel que TouchableOpacity.

2
Metalliza

J'ai une solution très simple en utilisant runAfterInteractions:

   _GoCategoria(_categoria,_tipo){

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

    };
0
André Alencar

Vous pouvez également afficher un gif de chargement pendant que vous attendez une opération asynchrone. Assurez-vous juste de baliser votre onPress avec async () => {} afin qu'il puisse être await '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;
0
zino