3

I am trying to understand the useRef hook in React.

I have created a simple time in react . The code for which is available below.

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

function Parent() {
  const [count,setCount]=useState(5);
  const ref=useRef(0);
//let hold=0;
  const countdown=()=>{
      ref.current=setInterval(()=>{
        // console.log('ref.current-->',ref.current);
        setCount((c)=>c-1)
       
      },1000)
  }
  useEffect(()=>{
    if(count<1)
        clearInterval(ref.current)
  },[count])
  
  return(
      <>
      <h3>Timer : {count}</h3>
      <br/>
      <button onClick={countdown}>countdown</button>
    </>
  )
}

export default Parent;

Here I have created a ref using the hook and I am monitoring the count state . When it hits 0 , I am calling the 'clearInteval' function to clear up the timer.

This code is working fine .

But when I try to do the same using a normal variable rather than the one created by the hook , the interval is not getting cleared .

Please find below the code for the same.

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

function Parent() {
  const [count,setCount]=useState(5);
  const ref=useRef(0);
let hold=0;
  const countdown=()=>{
    hold=setInterval(()=>{
        // console.log('ref.current-->',ref.current);
        setCount((c)=>c-1)
       
      },1000)
  }
  useEffect(()=>{
    if(count<1)
        clearInterval(hold)
  },[count])
  
  return(
      <>
      <h3>Timer : {count}</h3>
      <br/>
      <button onClick={countdown}>countdown</button>
    </>
  )
}

export default Parent;

What am I not understanding here ?

This code should have worked in normal javaScript.

Ashutosh Kumar
  • 381
  • 2
  • 6
  • 18
  • `ref` doesn't change on every render (execution of `Parent` function). Meanwhile on each render , `hold` is declared and initialized every time as new variable. Same applies for `countdown` function too. – Lakshya Thakur Jul 13 '21 at 17:51

1 Answers1

6

const myRef = useRef() will provide a ref object such that myRef.current's value will persist across renders. When you use let myVar = something, myVar will be re-created on each render, so you will lose and replace its value each time.

Your Parent component is getting re-rendered each time your state changes, so you benefit from keeping your interval reference as a ref from useRef.

Chris Farmer
  • 24,974
  • 34
  • 121
  • 164