Home > Blockchain >  Run set interval when click from another component React
Run set interval when click from another component React

Time:02-22

i want to trigger countdown of 60 seconds when user click from another component . so far i didn't find any solution

 const [seconds, setSeconds] = useState(60)
 useEffect(() => {
    console.log(state.Trade.length ,"woking in useeffect ");
    setInterval(() => {
      setSeconds(prevState => prevState - 1)
    }, 1000);
 }, [state.Trade.length]);


 // also use without use effect 


    const startCounter = () => { 
  setInterval(() => {
    setSeconds(prevState => prevState - 1)
  }, 1000);
 }
if (state.Trade.length!=0) {
  if (seconds==0) return null
  startCounter()
 
}else{
  return null
}

it is not working i search a lot but did not find.Thanks

CodePudding user response:

Remember to clear your interval

const [seconds, setSeconds] = useState(60);
useEffect(() => {
    const intervalId = setInterval(() => {
      setSeconds((prevState) => {
        if(prevState === 1) clearInterval(intervalId)
        return prevState - 1;
      });
    }, 1000);
}, [state.Trade.length]);

CodePudding user response:

The useEffect will trigger when state.Trade.length changes.

You probably need to have a dependency to seconds.

Something like this:

const [seconds, setSeconds] = useState(60)
 useEffect(() => {
    console.log(state.Trade.length ,"woking in useeffect ");
    setInterval(() => {
      setSeconds(prevState => prevState - 1)
    }, 1000);
 }, [seconds]);

Note that this has 2 issues:

  1. Linters will complain about not having state.Trade.length as dep, but you're just using this to console the value
  2. setInterval just uses the time as a hint. If you want a proper countdown. You should measure the time between 2 invocations and adjust the 1000ms interval.

CodePudding user response:

I can give you some pointer to try based on the question you are asking & the code you have given for reference.

  1. Dont pass any dependency in the useEffect as it will be executed only when the dependency changes. Keep the dependency array blank then it will work like componentDidMount().
  2. You can simply use setTimeOut() function to wait for 60 seconds when the component is mounted and then do your logic in that.
  3. I dont recommend using setSeconds in useEffect when its dependency is seconds variable itself. This might cause an infinite render (as given in one of the answer here).

Edit 1: So what I am doing below is changing the state variable to 1 on a button click to simulate your scenario. Then in one useEffect I am setting an interval to do -1 for the seconds variable which is 5 here but you can make it 60. On ummount, the interval will be cleared. The second useEffect is just logging when the seconds changes every second.

const[state,setState]=useState(0)
const[seconds, setSeconds]=useState(5)
useEffect(()=>{
    let secondsInterval;
    if(state===1){
        secondsInterval=setInterval(()=>{
            setSeconds(prev=>prev-1)
        },1000)
    }
    return()=>clearInterval(secondsInterval)
},[state])

useEffect(()=>{
    console.log("Time remaining: " seconds);
},[seconds])
  • Related