Skip to content
Advertisement

Access React state of function enclosed inside useRef doesn’t update

I’m trying to access React state inside a function enclosed inside of useRef. However, even with a helper function bound to App to access the state, the state never updates inside of the useRef function.

getCount outside 0
// after clicking, getCount inside is still 0, even though count now equals 1
getCount outside 1
getCount inside 0
import React, { useState, useRef } from 'react'
import ReactDOM from 'react-dom'

const App = function () {
  const [count, setCount] = useState(0)

  const getCount = function () {
    return count
  }.bind(App)

  console.log('getCount outside', getCount())

  const onClick = useRef(() => {
    console.log('getCount inside', getCount())
  })

  return (
    <>
      <div onClick={() => setCount(count + 1)}>
        increment count
      </div>
      <div onClick={onClick.current}> 
        {count}
      </div>
    </>
  )
}

const wrapper = document.getElementById('root')
ReactDOM.render(<App />, wrapper)

Advertisement

Answer

The argument passed to useRef is only considered when the component mounts. Only at that time is the value assigned to the ref; it won’t update when the component re-renders.

When the component mounts, the count variable that the ref’s function closes over is the initial state value, which is 0. No matter how many times the component re-renders, the ref’s function, if not reassigned, will still close over that original state value.

If you want the ref’s function to result in an up-to-date value, assign it anew each time there’s a re-render.

// assign nothing notable on mount, just create a ref
const onClickRef = useRef();
// on mount and on re-render, assign a function
// with an up-to-date reference to the state variable
onClickRef.current = () => {
  console.log(count);
};

Though, in React, usually it’d be better to pass the state itself down and use it, rather than a ref – refs are generally for things that you can’t accomplish using the more functional tools provided by React.

Advertisement