Как обрабатывать setInverval и clearInterval в react native

#typescript #react-native

#typescript #react-native

Вопрос:

Я хочу изменять значение состояния [time] каждую секунду при нажатии кнопки. У меня есть приведенный ниже код, но, к сожалению, код не работает. У вас есть какие-либо предложения о том, как я могу справиться с этой проблемой?

Большое спасибо!

 import React,{useState} from 'react';
import {View,Text,StyleSheet,TouchableOpacity} from 'react-native';
import { AntDesign } from '@expo/vector-icons';

const TimeButton = () =>{

  const [time,setTime] = useState(10)
  
  
  let intervalId:any = null;
 
  


  return(
    <View style={styles.container}>
      <TouchableOpacity>
         <AntDesign name="caretleft" size={24} color="black" />
      </TouchableOpacity>
      <Text>{time}</Text>
      <TouchableOpacity onPressIn={() => {
        intervalId = setInterval(setTime(time 1), 1000)

        }} onPressOut={() => clearInterval(intervalId)}>
          <AntDesign name="caretright" size={59} color="black" />
      </TouchableOpacity>
    </View>
  )
}

const styles = StyleSheet.create({
  container:{
    flex:1,
    flexDirection:'row',
    alignItems:'center',
    justifyContent:"center"
  }
})

export default TimeButton;
  

Комментарии:

1. Не используйте изменяемый local intervalId для хранения вашего intervalId. useState для этого, чтобы оно сохранялось.

Ответ №1:

Пожалуйста, проверьте эту демонстрацию, надеюсь, она вам поможетhttps://snack.expo.io/eUOetcDe6

     import React,{useState} from 'react';
    import {View,Text,StyleSheet,TouchableOpacity} from 'react-native';
    import { AntDesign } from '@expo/vector-icons';
    let intervalId;
    let Time=10;
    const TimeButton = () =>{
      const [time,setTime] = useState(Time)
      const StartInterval=()=>{
            intervalId=setInterval(() => {
              Time  ;
              setTime(Time);
            }, 1000);
      }
      const StopInterval=()=>{
        clearInterval(intervalId);
      }
      return(
        <View style={styles.container}>
            <TouchableOpacity style={{backgroundColor:'black',padding:10}} onPress={StartInterval}>
              <Text style={{color:'white',fontWeight:'bold'}}>Start</Text>
          </TouchableOpacity>
            <Text>{time}</Text>
          <TouchableOpacity style={{backgroundColor:'#6200ee',padding:10}} onPress={StopInterval}>
            <Text style={{color:'white',fontWeight:'bold'}}>Stop</Text>
          </TouchableOpacity>

        </View>
      )
    }

    const styles = StyleSheet.create({
      container:{
        flex:.2,
        flexDirection:'coulam',
        alignItems:'center',
        justifyContent:"space-around"
      }
    })

    export default TimeButton;
  

Комментарии:

1. Это сработало ! Большое вам спасибо за вашу помощь. Если вы не возражаете, не могли бы вы объяснить мне, почему «intervalId», если он находится в TimeButton, функция clearinterval не работает?

2. Логика очень проста, когда каждое ваше состояние обновляется, компонент снова будет отображаться, поэтому через 1 секунду ваша переменная intervalId изменяется с setInterval на null

3. 2 вызова StartInterval приведут к потере intervalId для первого таймера. Вы можете выбрать вызов StopInterval из StartInterval , чтобы убедиться, что вы никогда не потеряете никаких дескрипторов таймера.

4. Разве это не плохая практика обновлять состояние вне функционального компонента? Как и в, setInterval было установлено значение intervalId вне компонента, поэтому технически setInterval вызывается функция, которая также включает setTime «извне» компонента, нет?

Ответ №2:

обратите внимание, что setInterval выполняется обратный вызов (необычное имя для передачи функции другой функции), поэтому использование setInterval должно быть похоже

    onPressIn={() => { 

              intervalId = setInterval(() => setTime(time 1), 1000));

   }};
  

и пока вы выполняете какую-либо асинхронную операцию, я не буду использовать setTime на основе старого состояния, которое при использовании могло быть изменено, поэтому для большей определенности используйте функциональную версию setTime для обновления состояния time

   setTime(oldTime => oldTime   1);
  

Комментарии:

1. Внешний setInterval (без периода времени), который вызывает внутренний setInterval , который не использует функцию для своего 1-го параметра? Это не имеет никакого смысла.

2. извините, я допустил ошибку при написании решения, я это исправлю