Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 反应倒计时计时器不';t递减,它是不一致地改变数字_Reactjs - Fatal编程技术网

Reactjs 反应倒计时计时器不';t递减,它是不一致地改变数字

Reactjs 反应倒计时计时器不';t递减,它是不一致地改变数字,reactjs,Reactjs,倒计时不正确,当倒计时到50秒时,它开始发疯,我认为问题在我的使用范围内,但我不能指出它, import React, { useState, useCallback, useEffect, useRef } from 'react' function App() { const [minute,setMinute]=useState(1) const [second,setSecond]=useState(3) const[start,setStart]=useState(

倒计时不正确,当倒计时到50秒时,它开始发疯,我认为问题在我的使用范围内,但我不能指出它,

import React, { useState, useCallback, useEffect, useRef } from 'react'

function App()
{
   const [minute,setMinute]=useState(1)
   const [second,setSecond]=useState(3)
   const[start,setStart]=useState(false)

const IntervalRef=useRef()
useEffect(()=>{
    if(start==true)
    {
      IntervalRef.current=setInterval(()=>{
            if(second!=0)   
            {
                setSecond(second-1)
            }
            if(second==0&&minute!=0)
            {
                setSecond(59)
                setMinute(minute-1)
            }
            else
            {
                    clearInterval(IntervalRef.current)
            }
       },1000)
    }
})

    return(
       <div>
           {minute}:{second}
    <button onClick={()=>setStart(!start)}>{start?"pause":"start"}</button>

       </div>
    )
}

export default App
import React,{useState,useCallback,useffect,useRef}从'React'导入
函数App()
{
const[minute,setMinute]=useState(1)
常数[秒,设置秒]=使用状态(3)
const[start,setStart]=useState(false)
const IntervalRef=useRef()
useffect(()=>{
if(start==true)
{
IntervalRef.current=setInterval(()=>{
如果(秒!=0)
{
设置秒(秒-1)
}
如果(秒==0和分钟!=0)
{
秒(59)
设置分钟(分钟-1)
}
其他的
{
清除间隔(间隔参考电流)
}
},1000)
}
})
返回(
{分钟}:{秒}
setStart(!start)}>{start?“暂停”:“start”}
)
}
导出默认应用程序

它没有正确倒计时,当它达到50秒时开始疯狂,我认为问题出在我的useEffect中,但我不能指出它,

您应该在每个效果运行后清除间隔,因为效果会运行每个渲染周期并每次重新创建间隔。该效果在每次状态更新后再次运行。我怀疑一些时钟偏差也是罪魁祸首,这就是为什么你会看到状态更新变得“不同步”

import React, { useState, useCallback, useEffect, useRef } from 'react'

function App()
{
   const [minute,setMinute]=useState(1)
   const [second,setSecond]=useState(3)
   const[start,setStart]=useState(false)

const IntervalRef=useRef()
useEffect(()=>{
    if(start==true)
    {
      IntervalRef.current=setInterval(()=>{
            if(second!=0)   
            {
                setSecond(second-1)
            }
            if(second==0&&minute!=0)
            {
                setSecond(59)
                setMinute(minute-1)
            }
            else
            {
                    clearInterval(IntervalRef.current)
            }
       },1000)
    }
})

    return(
       <div>
           {minute}:{second}
    <button onClick={()=>setStart(!start)}>{start?"pause":"start"}</button>

       </div>
    )
}

export default App
改进后的组件可以只使用秒状态值,因为计算分钟数很简单

displayMinutes = Math.floor(seconds / 60);
displaySeconds = seconds % 60;
实施

function App() {
  const [seconds, setSeconds] = useState(63);
  const [start, setStart] = useState(false);

  const IntervalRef = useRef();
  useEffect(() => {
    if (start) {
      const tick = () => setSeconds(t => t - 1);
      IntervalRef.current = setInterval(tick, 1000);
    } else {
      clearInterval(IntervalRef.current)
    }

    return () => clearInterval(IntervalRef.current)
  }, [start]); // <-- start is dependency so effect runs on mount and only when start is updated

  return (
    <div>
      {Math.floor(seconds / 60)}:{seconds % 60}
      <button onClick={() => setStart(start => !start)}>
        {start ? "pause" : "start"}
      </button>
    </div>
  );
}
函数应用程序(){
常数[秒,设置秒]=使用状态(63);
const[start,setStart]=useState(false);
const IntervalRef=useRef();
useffect(()=>{
如果(启动){
常量tick=()=>setSeconds(t=>t-1);
IntervalRef.current=设置间隔(刻度,1000);
}否则{
清除间隔(间隔参考电流)
}
return()=>clearInterval(IntervalRef.current)
},[start]);//!start)}>
{开始?“暂停”:“开始”}
);
}

您应该在每次效果运行后清除间隔,因为效果会运行每个渲染周期并每次重新创建间隔。该效果在每次状态更新后再次运行。我怀疑一些时钟偏差也是罪魁祸首,这就是为什么你会看到状态更新变得“不同步”

改进后的组件可以只使用秒状态值,因为计算分钟数很简单

displayMinutes = Math.floor(seconds / 60);
displaySeconds = seconds % 60;
实施

function App() {
  const [seconds, setSeconds] = useState(63);
  const [start, setStart] = useState(false);

  const IntervalRef = useRef();
  useEffect(() => {
    if (start) {
      const tick = () => setSeconds(t => t - 1);
      IntervalRef.current = setInterval(tick, 1000);
    } else {
      clearInterval(IntervalRef.current)
    }

    return () => clearInterval(IntervalRef.current)
  }, [start]); // <-- start is dependency so effect runs on mount and only when start is updated

  return (
    <div>
      {Math.floor(seconds / 60)}:{seconds % 60}
      <button onClick={() => setStart(start => !start)}>
        {start ? "pause" : "start"}
      </button>
    </div>
  );
}
函数应用程序(){
常数[秒,设置秒]=使用状态(63);
const[start,setStart]=useState(false);
const IntervalRef=useRef();
useffect(()=>{
如果(启动){
常量tick=()=>setSeconds(t=>t-1);
IntervalRef.current=设置间隔(刻度,1000);
}否则{
清除间隔(间隔参考电流)
}
return()=>clearInterval(IntervalRef.current)
},[start]);//!start)}>
{开始?“暂停”:“开始”}
);
}