React Native put a “Cooldown” on a Button

南楼画角 提交于 2021-01-29 09:38:34

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!