【问题标题】:setState isn't working properly with onlongpress of touchableopacitysetState 无法与 touchableopacity 的 onlongpress 一起正常工作
【发布时间】:2020-12-02 02:21:27
【问题描述】:

我完全是 react-native 的菜鸟。我的目标是增加或减少计数器,直到用户按住按钮。为此,我正在使用 toucableopacity 的 onLongPress 道具,并尝试使用 SetTimeout() 函数以 400 毫秒的延迟更改状态。
但是,当长按激活时,它会更改一次值,然后不再更改。我查找了相关问题,每个人都提到这是因为 setstate 是异步的。但是为什么它会在调用超时之前更新一次值呢?
所以我最初的猜测是它与 settimeout 有关。或者,如果有人有任何其他解决方案来执行所需的操作,请帮助我。

import React, { Component, useState } from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
let timer = null;

function Untitled(props) {
  const [counter, setcounter] = useState(50);
  let dummy = counter;

  const timerhandler = () => {
    setcounter(counter - 1);
    console.log(counter);
    timer = setTimeout(timerhandler, 400);
  };

  const stopTimer = () => {
    console.log(counter);
    clearTimeout(timer);
  };
  return (
    <View style={styles.container}>
      <View style={styles.buttonStackStack}>
        <TouchableOpacity
          style={styles.button16}
          onLongPress={timerhandler}
          onPressOut={stopTimer}>
          <Text>Minus</Text>
        </TouchableOpacity>
        <Text>{counter}</Text>
        <TouchableOpacity style={styles.button16}>
          <Text>Plus</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}
export default function App() {
  return Untitled();
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    flexDirection: 'column',
    margin: 10,
  },
  buttonStackStack: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    flexDirection: 'row',
    alignItems: 'center',
    paddingTop: 5,
    justifyContent: 'center',
  },
  button16: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    alignItems: 'center',
    margin: 10,
    justifyContent: 'center',
  },
});

而且 settimeout 确实保持循环运行,直到 stopTimer 被调用,这可以通过 console.log() 输出来确认。

【问题讨论】:

  • 尝试添加delayLongPress={1000}
  • delayLongPress 不起作用。但是我的一个朋友建议我尝试使用减速器,这对我来说确实有效。所以我仍然不确定最初的问题是什么,但现在,我将使用减速器。我正在添加我的解决方案作为答案。

标签: javascript reactjs react-native


【解决方案1】:

所以我仍然不确定这里的真正问题是什么。但是在朋友的帮助下,我使用减速器解决了这个问题。这是对我有用的新代码。

import React, { Component, useState, useReducer } from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
let timer = null;
function reducer(state, action){
  if(action.type == 'minus'){
    if(state.count>1){
    console.log(state.count-1)
    return {count: state.count-1}}
    return state}
  else if(action.type == 'plus'){
    if(state.count<100){
    console.log(state.count+1)
    return {count: state.count+1}}
    return state}
}
function Untitled(props) {
  const [state, dispatch] = useReducer(reducer, {count:50});

  const timerhandler = () => {
    dispatch({type:'minus'})
    timer = setTimeout(timerhandler, 200);
  };
  const timerhandler2 = () => {
    dispatch({type:'plus'})
    timer = setTimeout(timerhandler2, 200);
  };

  const stopTimer = () => {
    // console.log(state.count);
    clearTimeout(timer);
  };
  return (
    <View style={styles.container}>
      <View style={styles.buttonStackStack}>
        <TouchableOpacity
          style={styles.button16}
          onLongPress={timerhandler}
          onPressOut={stopTimer}>
          <Text>Minus</Text>
        </TouchableOpacity>
        <Text>{state.count}</Text>
        <TouchableOpacity style={styles.button16}
          onLongPress={timerhandler2}
          onPressOut={stopTimer}>
          <Text>Plus</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
}
export default function App() {
  return Untitled();
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    flexDirection: 'column',
    margin: 10,
  },
  buttonStackStack: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    flexDirection: 'row',
    alignItems: 'center',
    paddingTop: 5,
    justifyContent: 'center',
  },
  button16: {
    flex: 1,
    backgroundColor: 'rgba(173,216,230,1)',
    borderWidth: 1,
    borderColor: '#000000',
    alignItems: 'center',
    margin: 10,
    justifyContent: 'center',
  },
});

【讨论】:

    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2019-08-29
    • 2017-12-14
    • 2020-08-19
    • 2013-02-06
    相关资源
    最近更新 更多