Javascript setInterval刷新应用程序,而不是更新状态
我正在用Javascript setInterval刷新应用程序,而不是更新状态,javascript,typescript,react-native,expo,setinterval,Javascript,Typescript,React Native,Expo,Setinterval,我正在用Expo编码倒计时。 我使用的是功能组件,因此我的状态是通过React的useState钩子处理的 let [state, setState] = useState({ secondsLeft: 25, started: false, }); 如果我按下按钮它会触发此功能: let onPressHandler = (): void => { if(!state.started) { setState({...state, started:
Expo
编码倒计时。
我使用的是功能组件
,因此我的状态
是通过React的useState
钩子处理的
let [state, setState] = useState({
secondsLeft: 25,
started: false,
});
如果我按下按钮
它会触发此功能:
let onPressHandler = (): void => {
if(!state.started) {
setState({...state, started: true});
setInterval(()=> {
setState({...state, secondsLeft: state.secondsLeft - 1});
console.log(state.secondsLeft);
}, 1000);
}
}
问题是每1000毫秒Expo刷新一次应用程序,而不是更新状态。
你能帮我吗?它更新状态,但它使用过时状态来更新。一旦间隔启动,
setInterval
回调中的state
变量将永远不会更改
相反,请使用状态更新函数的setter形式,以便始终使用当前状态:
let onPressHandler = (): void => {
if(!state.started) {
setState({...state, started: true});
setInterval(()=> {
setState(currentState => {
const newState = {...currentState, secondsLeft: currentState.secondsLeft - 1};
console.log(newState.secondsLeft);
return newState;
});
}, 1000);
}
};
没有控制台,它更简洁。log
:
let onPressHandler = (): void => {
if(!state.started) {
setState({...state, started: true});
setInterval(()=> {
setState(currentState => {...currentState, secondsLeft: currentState.secondsLeft - 1});
}, 1000);
}
};
另请注意:如果您有彼此独立更新的状态项,最佳实践是为它们使用单独的状态变量。此外,由于它们在函数中是常量,因此最好将它们声明为
const
。像这样:
const [secondsLeft, setSecondsLeft] = useState(25);
const [started, setStarted] = useState(false);
// ...
let onPressHandler = (): void => {
if(!started) {
setStarted(true);
setInterval(()=> {
setSecondsLeft(seconds => seconds - 1);
}, 1000);
}
};
此外,由于您不能完全依赖于setInterval
,因此我建议存储您的停止时间(“现在”加上25秒),并重新计算每次剩余的秒数:
let onPressHandler = (): void => {
const stopTime = Date.now() + (DURATION * 1000);
setStarted(true);
setSecondsLeft(DURATION);
const timer = setInterval(()=> {
const left = Math.round((stopTime - Date.now()) / 1000);
if (left <= 0) {
clearInterval(timer);
setStarted(false);
} else {
setSecondsLeft(left);
}
}, 1000);
};
let onPressHandler=():void=>{
const stopTime=Date.now()+(持续时间*1000);
设置开始(正确);
SetSecondLeft(持续时间);
常量计时器=设置间隔(()=>{
const left=Math.round((stopTime-Date.now())/1000);
如果(左){
常数持续时间=25;//秒
const[started,setStarted]=useState(false);
const[secondsLeft,setSecondsLeft]=useState(0);
如果(启动){
返回剩余秒数:{secondsLeft};
}
let onPressHandler=()/*:void*/=>{
const stopTime=Date.now()+(持续时间*1000);
设置开始(正确);
SetSecondLeft(持续时间);
常量计时器=设置间隔(()=>{
const left=Math.round((stopTime-Date.now())/1000);
如果(左)非常感谢您的非常清楚和详尽的解释!