Реагировать на родину

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

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

Ответы

Ответ 1

Возможно, вы могли бы использовать новую функцию отключения, введенную для сенсорных элементов в 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
}

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

Ответ 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>
    )
  }
}

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

Ответ 3

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

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

Ответ 4

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

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);

Ответ 5

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

Пример. Если вы хотите перейти от Home → About И дважды нажмите кнопку 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.

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

Ответ 6

Я использую вот так:

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