DEV Community

Cover image for How to fix React Hook warnings for async functions in useEffect
collegewap
collegewap

Posted on • Originally published at codingdeft.com

1

How to fix React Hook warnings for async functions in useEffect

When you try to execute an async activity inside the React useEffect hook, you might have seen the following warnings:

Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

return warning

useEffect function must return a cleanup function or nothing

async warning

Consider the following code:

import { useEffect, useState } from "react"

function App() {
  const [posts, setPosts] = useState([])

  useEffect(async () => {
    try {
      const response = await fetch(`https://jsonplaceholder.typicode.com/posts`)
      const data = await response.json()
      setPosts(data)
    } catch (e) {
      console.error(e)
    }
  }, [])

  return (
    <div className="App">
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Here, we are passing async function to the useEffect hook. As you may be aware, async functions return a Promise. However, useEffect expects the function to either return nothing or a clean up function. Hence reacts throws this warning.

There are 2 ways to fix this.

Moving async call to another function

We can define another function inside the useEffect and call it inside the useEffect as shown below:

import { useEffect, useState } from "react"

function App() {
  const [posts, setPosts] = useState([])

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch(
          `https://jsonplaceholder.typicode.com/posts`
        )
        const data = await response.json()
        setPosts(data)
      } catch (e) {
        console.error(e)
      }
    }
    fetchData()
  }, [])
  return (
    <div className="App">
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Now the function passed to useEffect returns nothing, thus by fulfilling the condition.

Also, you could prevent the race condition by cancelling previous requests.

Using .then() chaining

Instead of using async await syntax, we can use .then() to resolve the promise:

import { useEffect, useState } from "react"

function App() {
  const [posts, setPosts] = useState([])

  useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/posts`)
      .then(response => response.json())
      .then(data => {
        setPosts(data)
      })
      .catch(e => {
        console.log(e)
      })
  }, [])
  return (
    <div className="App">
      <ul>
        {posts.map(post => (
          <li key={post.id}>{post.title}</li>
        ))}
      </ul>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Now if you run the code, you should not be seeing the warning anymore.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay