React Hooks Gotchas: SetState in Async Effects

React Hooks Gotchas: SetState in Async Effects

React Hooks Gotchas: SetState in Async Effects. An async effect is an effect calling a promise and setting some state based on that promise. To reduce the number of renders, we have to reduce setState calls in async effects. One solution for that is grouping states that are logically bound to each other. Here, the pending and user states.

Let’s face it, hooks have been wandering around for a while now. Yet it feels like I discover new stuff every day. Today, I’d like to share a new discovery because it is very far from obvious − to say the least!

Small recap: an async effect

An async effect is an effect calling a promise and setting some state based on that promise.

import { useEffect } from 'react'

export default function App (): JSX.Element {
  useEffect(() => {
    // here's the promise
    fetch(…).then(() => {
      // …
    })
  }, [])
  …
}

With an example − Fetching a user

First approach

import React, { useEffect } from 'react'

export default function App (): JSX.Element {
  const [user, setUser] = useState(null)
  const [pending, setPending] = useState(false)

  useEffect(() => {
    setPending(true)
    fetchUser().then((fetchedUser) => {
      setPending(false)
      setUser(fetchedUser)
    })
  }, [])
  // …
}

The problem

Problem, what problem ?

Using this approach, the <App /> component will render 4 times:

  • Render 1: initial mount
  • Render 2: setPending(true) in the useEffect() causes the second render
  • Render 3: setPending(false) in the fetchUser().then()
  • Render 4: setUser(fetchedUser) in the fetchUser().then()

The problem is: in fetchedUser().then(), we triggered two setStates, and instead of having one render as expected, we have one render per **setState** call.

Important note:This happens only with async actions (aka promises in `useEffect_`). When a `useEffect()` does not trigger any async action, the `setState_`s are batched properly.

The solution: Grouping states that go together

To reduce the number of renders, we have to reduce setState calls in async effects. One solution for that is grouping states that are logically bound to each other. Here, the pending and user states.

import React, { useEffect } from 'react'

export default function App (): JSX.Element {
  const [user, setUser] = useState({ pending: false, value: undefined })

  useEffect(() => {
    setUser({ pending: true, value: undefined })

    fetchUser().then((fetchedUser) => {
      setUser({ pending: true, value: fetchedUser })
    })
  }, [])
  // …
}

Now it’s fine, we’ll have our 3 renders as expected.

react javascript web-development programming developer

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

How To Write Better Code As A Web Developer - React

Look at three different React code examples from a beginner, intermediate, and advanced web developer. How senior developers think. How to use React state properly. How to use React useEffect properly. What to think about when programming. The differences between senior and junior developers

How to Become A React JavaScript Developer 🚀

Today Qazi & Sonny will be showing you How To Become a React JavaScript Developer 🚀👨‍💻

Hire Dedicated React Native Developer

Have you ever thought of having your own app that runs smoothly over multiple platforms? React Native is an open-source cross-platform mobile application framework which is a great option to create mobile apps for both Android and iOS. **[Hire...

Top 10 Web Development Trends in 2020 | Web Development Skills

Top 10 Web Development Trends in 2020 will provide you with a detailed list of the trends which are currently being noticed. Upskilling to these trends will help you in landing onto better jobs in 2020-2021.