Back to all notes

First Render Detection: Skip useEffect for One‑Time Render Logic

Use a ref to run logic only on the first render without effects.

1 min read

Sometimes I need logic to run exactly once, on the first render. The reflex is an effect with a flag in state, but that runs after paint and costs an extra render.

Why Not an Effect

import { useState, useEffect } from "react";

function App() {
  const [isFirst, setIsFirst] = useState(true);

  useEffect(() => {
    if (isFirst) {
      console.log("First render");
      setIsFirst(false);
    }
  }, [isFirst]);

  return (
    <div>
      <h1>First Render Detection</h1>
      <p>Check console for first render log</p>
    </div>
  );
}

export default App;

The state starts true, the effect flips it and triggers a second render, all to track something that is only true once. And since effects run after paint, work that belonged in render has already missed its moment.

A Ref Checked During Render

A ref survives renders without causing any, which makes it the better flag.

import { useRef } from "react";

function App() {
  const isFirstRender = useRef(true);

  if (isFirstRender.current) {
    console.log("First render");
    isFirstRender.current = false;
  }

  return (
    <div>
      <h1>First Render Detection</h1>
      <p>Check console for first render log</p>
    </div>
  );
}

export default App;

useRef(true) starts as the first render. The check sits in the component body, the one-time logic runs, the ref flips to false, and every later render skips it. No effect, no extra render.

Render-Safe Logic Only

This runs during render, so the logic has to be free of side effects, or at least idempotent. If something truly must run after paint, useEffect with empty deps is still the right tool. And keep render-time flags in refs rather than state, because refs don’t trigger re-renders when they change.