#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. извините, я допустил ошибку при написании решения, я это исправлю