DEV Community

Discussion on: React 18 - Avoiding Use Effect Getting Called Twice

Collapse
 
iamyoki profile image
Yoki

Final code like this might be better.

function useEffectOnce(effect) {
  const effectFn = useRef(effect)
  const destroyFn = useRef()
  const effectCalled = useRef(false)
  const rendered = useRef(false)
  const [, refresh] = useState(0)

  if (effectCalled.current) {
    rendered.current = true
  }

  useEffect(() => {
    if (!effectCalled.current) {
      destroyFn.current = effectFn.current()
      effectCalled.current = true
    }

    refresh(1)

    return () => {
      if (rendered.current === false) return
      if (destroyFn.current) destroyFn.current()
    }
  }, [])
}
Enter fullscreen mode Exit fullscreen mode