【问题标题】:React clearInterval doesn't stop when using another state使用其他状态时反应 clearInterval 不会停止
【发布时间】:2022-02-15 23:56:32
【问题描述】:

我有一个小应用程序,当我按下播放时正在播放一些音频,当我使用 isPlaying 状态再次按下按钮时停止。播放/停止的功能效果很好,但我想添加一个进度条来显示歌曲的进度。我使用了 useEffect 和“完成”状态 这样进度条将显示 CSS 样式的进度。一切正常,除了我无法清除间隔。当我按下停止时,歌曲停止,但进度条继续,在检查后我发现 clearInterval 不起作用。这是我的 useEffect 函数:

  const ProgressBar = ({isPlaying}) => {
        const [completed, setCompleted] = useState({
            count: 0
        });
        
         useEffect(() => {
        if (isPlaying){
             setInterval(() => {
                setCompleted(completed.count+=5.8)
                if(completed.count > 99) {
                    setCompleted(completed.count=0);
                } 
            }, 1000);
        }
        else {
            clearInterval()
            
        }
    }, [isPlaying]);

我尝试添加:

const intervalId = setInterval(() => { ...

然后将intervalId传递给clear(intervalId) 但是我需要在此之前添加 - if (isPlaying) 的条件。 当我这样做时,我不能使用"else { clearInterval(intervalId)} 因为 IntervalId 在 else 范围内未定义。 我怎样才能通过它并清除间隔? 我尝试了多种方法,但由于某种原因不起作用。任何帮助将不胜感激!

已编辑:

我尝试控制台日志只是为了确保播放状态从播放/停止切换中获得更改,并且可以正常工作:

    useEffect(() => {
    if (isPlaying) {
        console.log("playing")
    }
    else {
        console.log("not playing")
    }

我有“ControlPanel”组件,因此无法使用按钮功能配置 ProgressBar 组件功能:

        const ControlPanel = ({
setIsLooping, isLooping, isPlaying, setIsPlaying}) => {
      return ( 
        <div> 
        <PlayButton>
            {!isPlaying ? (
            <button type="button" 
            className="play" 
            onClick={() => setIsPlaying(true)}> 
            <ImPlay2></ImPlay2> Play 
            </button>
            ) : (
            <button type="button"
            className="pause"
            onClick={() => setIsPlaying(false)}> 
            <ImStop></ImStop> Stop 
            </button> 
            )}
        </PlayButton>
            <Flex> .....

【问题讨论】:

  • 你能分享你的回购链接或 StackBlitz 吗?
  • setCompleted和completed是什么?使用状态?完成了.count 定义了吗?
  • 我用完成状态编辑了我的问题

标签: javascript reactjs react-hooks conditional-statements setinterval


【解决方案1】:

使用可以在ref中存储setInterval id

const intervalId = useRef(null)

useEffect(() => {
    if (isPlaying){
        intervalId.current = setInterval(() => {
            setCompleted(completed.count+=5.8)
            if(completed.count > 99) {
                setCompleted(completed.count=0);
            } 
        }, 1000);
    }
    else {
        clearInterval(intervalId.current)
    }

    // it's better to clean up your component
    return () => {
       clearInterval(intervalId.current)
    }

}, [isPlaying]);

【讨论】:

  • 这有效,但只有一次。当我再次按下播放时,进度条停留在最后一个状态,并且没有进度。我也收到一个错误:Uncaught TypeError: Cannot create property 'count' on number '11.6'(意味着状态不会重置为 0。我尝试添加 setCompleted(completed.count=0); 但随后出现进度条根本不起作用。
  • 您可以尝试将您的setInterval id 存储在state 中吗?
  • 是的,我试过了: const [intervalId, setIntervalId] = useState (useRef(null)) ////// 然后 : useEffect(() => { if (isPlaying){ setIntervalId(setInterval (() => { ...
猜你喜欢
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多