You mentioned best practice so I'll just cover what occurs to me. There's actually a lot of cool things at play here.

As others have mentioned useEffect runs after every render, including the first. It's effectively both componentDidMount and componentDidUpdate.

Render is running twice because the useEffect is changing react state after the first render.

  • First Render -> Sets up effect
  • Effect triggers immediately afterwards -> changes timeOfDay
  • React runs render again to deal with the new state of timeOfDay

The simplest fix would be to set the first timeOfDay as a default during the first render. This way it won't have to change during the effect.

  const [date, setDate] = useState(new Date())
  const [timeOfDay, setTimeOfDay] = useState(getTimeOfDay(date))

Then move the code to set timeOfDay inside the interval with setDate.

You can actually do better, though, because just by putting the time of day in react state you're breaking the minimal essential state principle, which is fairly important in declarative programming. (note: I just made up that term. I don't think there's a good term for it yet.) What I mean by this is that timeOfDay is entirely derived from date, which is already in react state, so there is no reason (besides performance issues) to have both held in react state. Anytime this happens you should consider eliminating the redundant state. In this case this would involve deleting the timeOfDay state and just writing

    <>
    Good {getTimeOfDay(date)}, Name
    </>

As far as I can tell, the only reason to ever hold onto timeOfDay as state is if your getTimeOfDay were expensive and if rendering happened more often than once a second, but even in that case you would just want to use reacts memoization. That would look like

const timeOfDay = useMemo(() => getTimeOfDay(date), [date]);

Looks similar, right? It's basically the same, but it only runs during the render, and therefore can't cause the double render issue you're having. Specifically, useMemo will run getTimeOfDay during the first render, but then will only rerun getTimeOfDay on any subsequent render if [date] has changed; otherwise it will return the previous timeOfDay that was used.

One last thing worth mentioning. You pass [date] into your useEffect, but this is actually wrong. It will work, but it's not the intended use case. That array is used to tell react what state the effect function is reading from to cause its side-effects, but you're not reading from date, so you don't need to rerun the effect when date changes. What you really want is to pass in []—no state. That way react knows that you side-effect doesn't depend on anything, and should only run once during the first render. Right now your use of an interval rather than a timeout is kind-of pointless, as react is canceling and reestablishing the interval on every render.

With all the changes I've described so far your component would look like.

const PersonalGreeting = (): ReactElement => {
  const [date, setDate] = useState(new Date())

  useEffect(() => {
    const timer = setInterval(() => {
      setDate(new Date())
    }, 1000)

    return () => {
      clearInterval(timer)
    }
  }, [])

  return (
    `Good ${getTimeOfDay(date)}, Name`
  )
}

I also switched to string templating, which I think is nicer, but that's more of an opinion.

Answer from R Esmond on Stack Overflow
🌐
React
react.dev › reference › react › useEffect
useEffect – React
If your Effect wasn’t caused by an interaction (like a click), React will generally let the browser paint the updated screen first before running your Effect. If your Effect is doing something visual (for example, positioning a tooltip), and the delay is noticeable (for example, it flickers), replace useEffect with useLayoutEffect.
🌐
DEV Community
dev.to › hkp22 › a-deep-dive-into-useeffect-best-practices-for-react-developers-3b93
A Deep Dive into `useEffect`: Best Practices for React Developers - DEV Community
September 4, 2024 - Since its introduction in React 16.8, useEffect has become essential for tasks that require synchronization with the outside world, such as fetching data, updating the DOM, and managing subscriptions. In this article, we'll explore the useEffect hook in depth, discussing its purpose, usage, and best practices to help you become more proficient in React development.
Discussions

Understanding React hook useEffect & best practice
You mentioned best practice so I'll just cover what occurs to me. There's actually a lot of cool things at play here. As others have mentioned useEffect runs after every render, including the first. It's effectively both componentDidMount and componentDidUpdate. Render is running twice because the useEffect is changing react ... More on stackoverflow.com
🌐 stackoverflow.com
UseEffect Best Practices
Some notes: Run your examples through prettier. They look horrible and no one writes React this way. Naming is notoriously hard. This will create more opportunities for bad names. I foresee giant functions that has some generic name like "runAfterFieldUpdate" which tells me nothing. Having an anonymous function forces you to write simpler side-effects. If you can't understand the logic inside of your useEffect just because it's anonymous, then I think you have bigger issues to tackle with your code. It's non-idiomatic. Very rarely do you see named functions defined in this type of way when an anonymous function is expected. More on reddit.com
🌐 r/reactjs
52
79
December 18, 2023
reactjs - What is the good practice to use React.JS useEffect hook for multiple states - Stack Overflow
Taking more control when to run which useEffect. ... And React actually encourage us to do that. More on stackoverflow.com
🌐 stackoverflow.com
August 9, 2021
what do you actually use useEffect for?
Basically anywhere i need to step out of react, such as referencing a dom node, using browser api's, fetching data, using local/session storage, these are all things outside of react scope also known as effects hence the name of the hook, useEffect, keep in mind react returns React elements and not pure html elements neither dom nodes hence the reason you need to pass a ref to the jsx element if you want to get the real dom node More on reddit.com
🌐 r/reactjs
116
54
March 22, 2023
🌐
Overreacted
overreacted.io › a-complete-guide-to-useeffect
A Complete Guide to useEffect — overreacted
React can’t guess what the function does without calling it. (The source doesn’t really contain specific values, it just closes over the name prop.) This is why if you want to avoid re-running effects unnecessarily, you can provide a dependency array (also known as “deps”) argument to useEffect:
🌐
Newline
newline.co › @RichardBray › useeffect-in-react-best-practices-and-common-pitfalls--52b2d5d7
useEffect in React: Best Practices and Common Pitfalls | newline
December 9, 2024 - In React development, the useEffect hook is a fundamental tool that allows you to manage side effects in function components. Side effects in React include operations like fetching data, subscribing to external data sources, manually modifying the DOM, and even handling timers.
🌐
React
react.dev › learn › you-might-not-need-an-effect
You Might Not Need an Effect – React
In general, whenever you have to resort to writing Effects, keep an eye out for when you can extract a piece of functionality into a custom Hook with a more declarative and purpose-built API like useData above. The fewer raw useEffect calls you have in your components, the easier you will find to maintain your application.
Top answer
1 of 2
1

You mentioned best practice so I'll just cover what occurs to me. There's actually a lot of cool things at play here.

As others have mentioned useEffect runs after every render, including the first. It's effectively both componentDidMount and componentDidUpdate.

Render is running twice because the useEffect is changing react state after the first render.

  • First Render -> Sets up effect
  • Effect triggers immediately afterwards -> changes timeOfDay
  • React runs render again to deal with the new state of timeOfDay

The simplest fix would be to set the first timeOfDay as a default during the first render. This way it won't have to change during the effect.

  const [date, setDate] = useState(new Date())
  const [timeOfDay, setTimeOfDay] = useState(getTimeOfDay(date))

Then move the code to set timeOfDay inside the interval with setDate.

You can actually do better, though, because just by putting the time of day in react state you're breaking the minimal essential state principle, which is fairly important in declarative programming. (note: I just made up that term. I don't think there's a good term for it yet.) What I mean by this is that timeOfDay is entirely derived from date, which is already in react state, so there is no reason (besides performance issues) to have both held in react state. Anytime this happens you should consider eliminating the redundant state. In this case this would involve deleting the timeOfDay state and just writing

    <>
    Good {getTimeOfDay(date)}, Name
    </>

As far as I can tell, the only reason to ever hold onto timeOfDay as state is if your getTimeOfDay were expensive and if rendering happened more often than once a second, but even in that case you would just want to use reacts memoization. That would look like

const timeOfDay = useMemo(() => getTimeOfDay(date), [date]);

Looks similar, right? It's basically the same, but it only runs during the render, and therefore can't cause the double render issue you're having. Specifically, useMemo will run getTimeOfDay during the first render, but then will only rerun getTimeOfDay on any subsequent render if [date] has changed; otherwise it will return the previous timeOfDay that was used.

One last thing worth mentioning. You pass [date] into your useEffect, but this is actually wrong. It will work, but it's not the intended use case. That array is used to tell react what state the effect function is reading from to cause its side-effects, but you're not reading from date, so you don't need to rerun the effect when date changes. What you really want is to pass in []—no state. That way react knows that you side-effect doesn't depend on anything, and should only run once during the first render. Right now your use of an interval rather than a timeout is kind-of pointless, as react is canceling and reestablishing the interval on every render.

With all the changes I've described so far your component would look like.

const PersonalGreeting = (): ReactElement => {
  const [date, setDate] = useState(new Date())

  useEffect(() => {
    const timer = setInterval(() => {
      setDate(new Date())
    }, 1000)

    return () => {
      clearInterval(timer)
    }
  }, [])

  return (
    `Good ${getTimeOfDay(date)}, Name`
  )
}

I also switched to string templating, which I think is nicer, but that's more of an opinion.

2 of 2
0

Final version:

const PersonalGreeting = (): ReactElement => {
  const [timeOfDay, setTimeOfDay] = useState(getTimeOfDay(new Date()))

  useEffect(() => {
    const timer = setInterval(() => {
      setTimeOfDay(getTimeOfDay(new Date()))
    }, 60000)

    return () => {
      clearInterval(timer)
    }
  }, [])

  return useMemo(() => {
    return (
      <PersonalGreetingContainer>
        <PersonalGreetingHeading weight="light">
          Good {timeOfDay},{' '}
          {givenName}
        </PersonalGreetingHeading>
      </PersonalGreetingContainer>
    )
  }, [givenName, timeOfDay])
}
🌐
Medium
medium.com › swlh › useeffect-best-practices-for-using-and-avoiding-it-ae3f047db871
useEffect: Best Practices for Using and Avoiding it. | by Aakash Garg | Medium
November 29, 2023 - We have done this a lot where we execute some sort of effect right when our app starts & intutively useEffect is the right place for that. Not that related but in React18 this runs twice!. Of course you can fix that by having a boolean variable that tracks if the effect has ran the first time and playing with it(still on overkill).
Find elsewhere
🌐
DEV Community
dev.to › hkp22 › reacts-useeffect-best-practices-pitfalls-and-modern-javascript-insights-g2f
React’s `useEffect`: Best Practices, Pitfalls, and Modern JavaScript Insights - DEV Community
January 13, 2025 - Don’t overuse useEffect for tasks that can be handled directly in render or with derived state. React and modern JavaScript go hand-in-hand.
🌐
LogRocket
blog.logrocket.com › home › how to use the useeffect hook in react: a complete guide
How to use the useEffect hook in React: A complete guide - LogRocket Blog
June 3, 2025 - Instead, think more about data flow and the state associated with effects because you run effects based on state changes across render cycles · Define the effect clearly — Write focused code for the side effect inside the useEffect callback
🌐
DEV Community
dev.to › wdp › best-practices-for-usestate-and-useeffect-in-react-4aea
Best Practices for useState and useEffect in React - DEV Community
January 18, 2024 - A simpler and more effective approach is to calculate the filtered list directly using useState, like this: import React, { useState } from 'react'; const fruits = ["Apple", "Banana", "Cherry"]; function FruitList() { const [searchTerm, ...
🌐
Chudovo
chudovo.com › react-useeffect-common-mistakes-and-how-to-avoid-them
React useEffect Common Mistakes and How to Avoid Them - Chudovo
March 5, 2026 - Learn how to use the React useEffect hook, avoid common mistakes, and see practical code examples and tips for best practices.
🌐
Randomize Blog
randomizeblog.com › home › reactjs › mastering useeffect in react: a complete guide
Mastering React useEffect: Guide, and Best Practices
February 1, 2025 - Learn React's useEffect hook with a complete guide, examples, best practices, debugging tips, and alternatives for efficient side effect management
🌐
Reddit
reddit.com › r/reactjs › useeffect best practices
r/reactjs on Reddit: UseEffect Best Practices
December 18, 2023 - So the only thing of value you'd want returned by a function called via the `useEffect(func, [])` method is that `func` returns the effect's unmount function. ... I think another benefit here might be that if you're using something like a performance profiler or any sort of debugging tools, it'll be easier to trace back to the exact function. We have the same practice with react.memo
🌐
Strapi
strapi.io › blog › what-is-react-useeffect-hook-complete-guide
What Is React useEffect Hook? Complete Guide and Examples
July 22, 2025 - The dependency array controls when React reruns a side effect. Understanding this array prevents performance issues and debugging nightmares around race conditions or infinite loops. When you omit the dependency array entirely, the effect runs after every render. This pattern is rarely what you want: useEffect(() => { console.log('fires on every render'); });
🌐
DEV Community
dev.to › colocodes › 6-use-cases-of-the-useeffect-reactjs-hook-282o
6 use cases of the useEffect ReactJS hook - DEV Community
September 18, 2021 - As we are using a timer inside the useEffect, It is a good practice to clear it before it gets set again by using the return statement of the useEffect, which gets executed before the main body of the useEffect hook gets evaluated (except for ...
🌐
W3Schools
w3schools.com › react › react_useeffect.asp
React useEffect Hooks
We should always include the second parameter which accepts an array. We can optionally pass dependencies to useEffect in this array.
🌐
Medium
medium.com › @stheodorejohn › 10-best-practices-for-efficient-state-and-side-effect-management-mastering-useeffect-in-react-c8278890335
10 Best Practices for Efficient State and Side Effect Management — Mastering useEffect in React | by Theodore John.S | Medium
July 22, 2023 - Handle Cleanup: Use the cleanup function returned by useEffect to clean up any resources or subscriptions to prevent memory leaks. The cleanup… ... Passionate self-taught front-end dev. HTML, CSS, JS, React | Creating pixel-perfect web experiences |
🌐
MCP Market
mcpmarket.com › home › agent skills › react useeffect best practices
React useEffect Best Practices - Claude Code Skill
3 weeks ago - It treats Effects as an 'escape hatch' for external system synchronization, teaching users how to avoid common pitfalls such as overusing Effects for derived state, user event responses, or state synchronization. By following these implementation patterns, developers can significantly reduce unnecessary re-renders, simplify component logic, and build more performant React applications.
🌐
Reddit
reddit.com › r/reactjs › what do you actually use useeffect for?
r/reactjs on Reddit: what do you actually use useEffect for?
March 22, 2023 -

Now that the new React doc is labelling useEffect as an escape hatch (along with useRef), I'm wondering what do you guys actually use useEffect for in your apps, not conceptually what you can use it for, but what you actually use it for. For instance, if you're using swr or react query for fetching, you don't actually have to import/use useEffect yourself for fetching anymore, although you can still do that conceptually.

It would be nice if you can also talk about something that you used to use useEffect to do, but switched to a new library/pattern as replacement.