2016-03-23 2 views
15

У меня есть TouchableHighlight, обертывающий текстовый блок, который при нажатии на него открывает новую сцену (которую я использую для реакции-native-router-flux). Все работает отлично, за исключением того, что если вы быстро коснитесь TouchableHighlight, сцена может отобразиться дважды. Я бы хотел, чтобы пользователь не мог быстро нажать эту кнопку.React Native Prevent Double Tap

Каков наилучший способ сделать это у коренных? Я заглянул в Систему ответчиков жестов, но нет никаких примеров или чего-то подобного, если вы новичок, как и я, сбивает с толку.

+0

Возможно, вы нашли решение? – molerat

ответ

2

Возможно, вы можете использовать новую функцию отключения, введенную для сенсорных элементов в 0,22? Я имею в виду что-то вроде этого:

Компонент

<TouchableHighlight ref = {component => this._touchable = component} 
        onPress={() => this.yourMethod()}/> 

Метод

yourMethod() { 
    var touchable = this._touchable; 
    touchable.disabled = {true}; 

    //what you actually want your TouchableHighlight to do 
} 

Я не пробовал сам. Поэтому я не уверен, работает ли это.

1

Вы можете отскочить щелчок по фактическим методам приемника, особенно если вы имеете дело с состоянием визуальных эффектов.

_onRefresh() {  
    if (this.state.refreshing) 
     return 
    this.setState({refreshing: true}); 
2

Что вы пытаетесь сделать, так это то, что вы хотите ограничить свои обратные вызовы, чтобы они работали только один раз.

Это называется дросселированием, и вы можете использовать underscore для этого: Вот как:

_.throttle(
    this.thisWillRunOnce.bind(this), 
    200, // no new clicks within 200ms time window 
); 

Вот как мои реагировать компонент выглядит после того, как все.

class MyComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    _.throttle(
     this.onPressThrottledCb.bind(this), 
     200, // no new clicks within 200ms time window 
    ); 
    } 
    onPressThrottledCb() { 
    if (this.props.onPress) { 
     this.props.onPress(); // this only runs once per 200 milliseconds 
    } 
    } 
    render() { 
    return (
     <View> 
     <TouchableOpacity onPress={this.onPressThrottledCb}> 
     </TouchableOpacity> 
     </View> 
    ) 
    } 
} 

Надеюсь, это вам поможет. Если вы хотите узнать больше, проверьте this thread.

+0

Таким образом, я не мог передать параметры функции, подобной этой 'onPress = {() => this.onPressThrottledCb (data)}' – TomSawyer

+0

lodash или реализация подчеркивания дроссельной заслонки автоматически передают все параметры функции – mvandillen

+0

Теперь, используя underscore, и параметры передаются. – SudoPlz

0

следующие работы по предотвращению маршрутизации к тому же маршруту дважды:

import { StackNavigator, NavigationActions } from 'react-navigation'; 

const App = StackNavigator({ 
    Home: { screen: HomeScreen }, 
    Details: { screen: DetailsScreen }, 
}); 

// Prevents double taps navigating twice 
const navigateOnce = (getStateForAction) => (action, state) => { 
    const { type, routeName } = action; 
    return (
     state && 
     type === NavigationActions.NAVIGATE && 
     routeName === state.routes[state.routes.length - 1].routeName 
    ) ? state : getStateForAction(action, state); 
}; 
App.router.getStateForAction = navigateOnce(App.router.getStateForAction); 
+1

Если вы используете тот же экран дважды, это не удастся. Например, приложение для викторины. –

+0

Да, поскольку в ответе говорится, что это работает, предотвращая переход на тот же маршрут дважды. Если это не подходит, используйте другой метод. В большинстве случаев он подходит –

0

Я исправил эту ошибку, создав модуль, который вызывает функцию только один раз в прошедшем интервале.

Пример: Если вы хотите перейти от Home -> About И дважды нажмите кнопку «О программе», скажем, 400 мс.

navigateToAbout =() => dispatch(NavigationActions.navigate({routeName: 'About'})) 

const pressHandler = callOnce(navigateToAbout,400); 
<TouchableOpacity onPress={pressHandler}> 
... 
</TouchableOpacity> 
The module will take care that it calls navigateToAbout only once in 400 ms. 

Вот ссылка на модуль НПМ: https://www.npmjs.com/package/call-once-in-interval

0

я использую как это:

link(link) { 
     if(!this.state.disabled) { 
      this.setState({disabled: true}); 
      // go link operation 
      this.setState({disabled: false}); 
     } 
    } 
    render() { 
     return (
      <TouchableHighlight onPress={() => this.link('linkName')}><Text>Go link</Text></TouchableHighlight> 
     ); 
    }