Skip to content

Component doesn’t update once the parents state is changed

I’m attempting to get a timer to call a function quickly at first and then slow down. I have a TimeInterval state that increases and is passed down to my countdown component as a prop

<Countdown
      isActive={RandominatorRunning}
      target={() => NextSelection()}
      timeToChange={TimeInterval}
  />

Countdown Component

import React, { useEffect } from 'react';

const Countdown = ({ isActive, target, timeToChange }) => {


    useEffect(() => {
        let interval = null;
        if (isActive) {
            interval = setInterval(() => {
                target()
            }, timeToChange)
        } else if (!isActive) {
            clearInterval(interval)
        }
        return () => clearInterval(interval)
    }, [isActive])

    return null
}

export default Countdown;

My TimeInterval state is working properly and will increase as NextSelection() is called. However this doesn’t seem to increase the interval of the countdown component and NextSelection() is always called at the same pace, not at the changing state TimeInterval pace. Why is the countdown component not updating it’s pace along with the TimeInterval state?

Answer

Not positive this is the best solution, but I was able to alter my countdown component to get the desired effect.

I changed my countdown component to become inactive while it executes the prop update, then resumes as soon as the prop has finished updating.

import React, { useEffect, useState } from 'react';

const Countdown = ({ isActive, target, timeToChange }) => {

    const [Active, setActive] = useState(isActive)

    const handleTimeExpire = async () => {
        await target()
        setActive(true)
    }

    useEffect(() => {
        let interval = null;
        if (Active) {
            interval = setInterval(() => {
                setActive(false)
                handleTimeExpire()
            }, timeToChange)
        } else if (!Active) {
            clearInterval(interval)
        }
        return () => clearInterval(interval)
    }, [Active])

    return null
}

export default Countdown;