DEV Community

Discussion on: Avoiding useEffect with callback refs

Collapse
 
smlka profile image
Andrey Smolko

Good job! I would like to add my 2 cents. You mentioned that "React will run this [incline] function after every render". I would say that such inline functions will be called twice per rerender (null as argument then node as argument). Technically a prev function instance will be called with null (ref is unset) and a new function instance will be called with a node (ref is set):

import {useState} from 'react'

export default function MeasureExample() {
  const [height, setHeight] = useState(0)
  const [h, setH] = useState(0)

  const measuredRef = (node => {
    console.log(node, h)
    if (node !== null) {
      setHeight(node.getBoundingClientRect().height)
    }
  })

  return (
    <>
      <h1 ref={measuredRef}>Hello, world</h1>
      <h2 key={h}>The above header is {Math.round(height)}px tall</h2>
      <button onClick={()=>{setH(h+1)}}>Click</button>
    </>
  )
}

// after click
// null 0 - pre ref is unset, prev value of state is used
// <h1>Hello world</h1> 1 - new ref is set, new value of state is used
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tkdodo profile image
Dominik D

You're right, it will run once with null for the previous node, and then once more with the new node.

There are apparently some plans to "fix" callback refs by allowing them to return a cleanup function like useEffect does: twitter.com/dan_abramov/status/155...