问题
my question is if it is possible to put a cooldown on a button that the user presses, or to only register like 1 press in 2 seconds. I am using React Native (Expo) connected with a REST API and a PostgreSQL DB.
My problem is that I have a Button that sends data to a Database. OnPress the entered Values are PUT to the database and the User gets navigated to another Screen where he can see his entry.
I noticed that when a user is fast enought he can press the button twice or 3 times and therefore the data also is posted 2/3 times to the db.
I would need something like one second cooldown so the data is only posted 1 time because the navigation almost happens immediatly!
I could not find anything in the internet on this.
Thanks ~Faded
回答1:
Make the button disabled as soon as it's pressed.
const MyComponent = ({makePutCall}) => {
const [disabled,setDisabled] = useState(false);
const doPut = async () => {
setDisabled(true);
await makePutCall();
setDisabled(false);
}
return <Button disabled={disabled} onPress={doPut}/>
}
or use a ref to prevent pushing more than once:
const MyComponent = ({makePutCall}) => {
const disabled = useRef(false);
const doPut = async () => {
if(disabled.current) return;
disabled.current = true;
await makePutCall();
disabled.current = false;
}
return <Button onPress={doPut}/>
}
My person favourite is a spinner, like you said:
const MyComponent = ({makePutCall}) => {
const [showSpinner,setShowSpinner] = useState(false);
const handlePress = async () => {
setShowSpinner(true);
await makePutCall();
setShowSpinner(false);
}
return showSpinner ? <Spinner/> : <Button onPress={handlePress}/>
}
or do it another way - DON'T USE A TIMER.
回答2:
There are 2 solutions I can think of as of now, there might be many other solution as well.
Solution 1: Have some variable which can keep a value if database call has already been done, once you get response from database you can reset that variable and user can press that button again.
Something like
onPress = {this.state.isPressed ? null : <this.writeTodatabase>}
and
writeTodatabase = () => {
this.setState({ isPressed:true })
// code to write to database
// once you have response from database you can set isPressed to false.
}
You can also disable button if that variable is true.
Solution 2: You can use throttle
from lodash
library.
Reference Document
回答3:
try using debounce/throttle. here is a basic example of debounce.
Import * as _ from lodash;
...
...
onPressDebounced = _.debounce(this.onPressed(),500);
render() {
return (
<TouchableHighlight
{ ...this.props }
onPress = { this.onPressDebounced}>
{this.props.children}
</TouchableHighlight>
)
}
来源:https://stackoverflow.com/questions/64008592/react-native-put-a-cooldown-on-a-button