反应导航防止两次push()

时间:2020-03-06 15:24:15

标签: react-native react-navigation

我正在使用react-navigation-4.2.1。构建一个应用程序。该应用程序具有多个堆栈导航器。因此,有许多navigation.push('Routename')调用。 问题是当控制表面(即TouchableOpacity)被快速敲击多次(第一次,而在屏幕转换期间剩下的)时,我最终将多个屏幕推入堆栈中。有没有一种方法可以将表面限制为push()的第一次敲击/调用?

1 个答案:

答案 0 :(得分:2)

以下组件是我用来使事物可触摸的组件。它可以在短时间内处理多次触摸。

  • 使用下面的组件代替TouchableOpacity。用此组件包装任何您想要的东西,它将是可触摸的。
<SafeTouch
    onPress={...}
>
    <Text> hey! im a touchable text now</Text>
</SafeTouch>
  • 下面的组件使用TypeScirpt编写。
  • 第一次触摸后300毫秒内的每次触摸都将被忽略(这可以帮助您解决问题)。
import * as React from 'react'
import { TouchableOpacity } from 'react-native'

interface ISafeTouchProps {
    onPress: () => void
    onLongPress?: () => void
    onPressIn?: () => void
    onPressOut?: () => void,
    activeOpacity?: number,
    disabled?: boolean,
    style: any
}

export class SafeTouch extends React.PureComponent<ISafeTouchProps> {
    public static defaultProps: ISafeTouchProps = {
        onPress: () => { },
        onLongPress: () => { },
        onPressIn: () => { },
        onPressOut: () => { },
        disabled: false,
        style: null
    }
    private isTouchValid: boolean = true
    private touchTimeout: any = null
    public constructor(props: ISafeTouchProps) {
        super(props)
        {// Binding methods
            this.onPressEvent = this.onPressEvent.bind(this)
        }
    }
    public render(): JSX.Element {
        return (
            <TouchableOpacity
                onPress={this.onPressEvent}
                onLongPress={this.props.onLongPress}
                onPressIn={this.props.onPressIn}
                onPressOut={this.props.onPressOut}
                activeOpacity={this.props.activeOpacity}
                disabled={this.props.disabled}
                style={[{minWidth: 24, minHeight: 24}, this.props.style]}
            >
                {
                    this.props.children
                }
            </TouchableOpacity>
        )
    }
    public componentWillUnmount() {
        this.clearTimeoutIfExists()
    }
    private onPressEvent(): void {
        requestAnimationFrame(() => {
            if (this.isTouchValid === false) {
                return
            }
            this.isTouchValid = false
            this.clearTimeoutIfExists()
            this.touchTimeout = setTimeout(() => {
                this.isTouchValid = true
            }, 300)
            if (typeof this.props.onPress === 'function') {
                this.props.onPress()
            }
        })
    }
    private clearTimeoutIfExists(): void {
        if (this.touchTimeout != null) {
            clearTimeout(this.touchTimeout)
            this.touchTimeout = null
        }
    }
}