问题描述
我希望按钮在每次正常按下时都增加一个,并在长按按钮时一直增加,直到释放为止。
我正在使用TouchableOpacity longpress属性启动setInterval,看来外部道具已正确调用。但是,外部Counter组件确实会在内部更新状态,但是我们看不到任何呈现在屏幕上的更新。仅当释放按钮并再次按下(一次)时,我们才能看到它是伪装的。
为什么会这样?这是longpress属性的问题吗?
这是小吃: https://snack.expo.io/xXP_PiqIy
代码如下:
import React,{ useRef,useState } from 'react';
import { Text,View,StyleSheet,TouchableOpacity } from 'react-native';
export default function App() {
const [count,setCount] = useState(10)
return (
<View style={{ flex: 1,justifyContent: "center",alignItems: "center" }}>
<Text>{count}</Text>
<CounterButton onPress={(count) => setCount(count)} initialCount={10} />
</View>
);
}
const CounterButton = (props) => {
const [count,setCount] = useState(props.initialCount ?? 0);
const onPress = () => {
props.onPress(count + 1);
setCount((count) => count + 1);
};
return <MultiTouchable onPress={onPress} text={' + '} />;
};
const MultiTouchable = (props) => {
const isPressing = useRef(false);
const timer = useRef();
const onPress = () => {
props.onPress();
};
const onLongPress = () => {
isPressing.current = true;
timer.current = setInterval(onPress,200);
};
const cancelLongPress = () => {
if (isPressing.current) {
clearInterval(timer.current);
isPressing.current = false;
}
};
return (
<TouchableOpacity
style={{ width: 50,height: 50,alignItems: "center",backgroundColor: 'lightblue' }}
onPressIn={onPress}
onLongPress={onLongPress}
onPressOut={cancelLongPress}>
<Text>{props.text}</Text>
</TouchableOpacity>
);
};
解决方法
这是挂钩(功能示例)可能会帮助
import React from "react";
import {
SafeAreaView,View,Dimensions,TouchableOpacity,Text
} from "react-native";
const App (props) => {
const [counter,setCounter] = React.useState(0);
const [timer,setTimer] = React.useState(null);
const addOne = () => {
setCounter( counter + 1 );
setTimer(setTimeout(addOne,200) );
};
const stopTimer = () => {
clearTimeout(timer);
};
render() {
return (
<SafeAreaView>
<View style={{ flex:1 }}>
<TouchableOpacity
style={{ backgroundColor: "#FFC0CB" }}
onPressIn={addOne}
onPressOut={stopTimer}
>
<Text>Press to start</Text>
</TouchableOpacity>
<Text>{counter}</Text>
</View>
</SafeAreaView>
);
}
}
,
看起来问题根本不是长按。
我需要更新计数器,并且在setCounter回调内部内调用props.onPress
如果有人可以在评论中解释为什么需要在这里完成,那么我将非常高兴。
// CounterButton
// ❌ doesn't work
const onPress = () => {
props.onPress(count + 1);
setCount((count) => count + 1);
};
// ✅ works
const onPress = () => {
setCount((count) => {
onPress(count + 1);
return count + 1;
});
};