Swizec Teller - a geek with a hatswizec.com

Senior Mindset Book

Get promoted, earn a bigger salary, work for top companies

Senior Engineer Mindset cover
Learn more

    React can update state during render

    After years of using React, it still packs a surprise. Did you know you can update state while rendering?

    Yep. From the docs:

    If you're like me, you wouldn't think to do this. You'd go with a useEffect instead.

    Updating state during render is unintuitive because every setState triggers a re-render, but you're rendering right now. So how can you re-render while rendering without breaking something?

    The clue comes in a different part of the docs, in the setState caveats section:

    Calling the set function during rendering is only allowed from within the currently rendering component. React will discard its output and immediately attempt to render it again with the new state. This pattern is rarely needed, but you can use it to store information from the previous renders.

    It's a performance and UX optimization of sorts. Here's the difference.

    With useEffect

    A counter component that resets to a new number when props change.

    const Comp = ({ number }) => {
      const [realNumber, setRealNumber] = useState(number)
    
      useEffect(() => {
        setRealNumber(number)
      }, [number])
    
      // ...
    }
    
    1. Component renders with value in state
    2. Effect runs
    3. State updates
    4. Component re-renders with new state

    You get a flash of stale state.

    With update during render

    A counter component that resets to a new number when props change.

    const Comp = ({ number }) => {
      const [realNumber, setRealNumber] = useState(number)
      const [prevProp, setPrevProp] = useState(number)
    
      if (prevProp !== number) {
        setRealNumber(number)
        setPrevProp(number)
      }
    
      // ...
    }
    
    1. Component starts rendering
    2. State updates
    3. React bails and re-starts render
    4. Component renders with new state

    No flash of stale state, fewer spooky interaction effects between various useEffect, a more stable experience for both you and the user. Yay.

    Yes it does work

    Here's a Codesandbox. I had to prove to myself that this works. Going to be useful in a few special cases like updating default values for form fields and menus that hide on scroll.

    Cheers,
    ~Swizec

    Published on June 30th, 2023 in Frontend, JavaScript, React

    Did you enjoy this article?

    Continue reading about React can update state during render

    Semantically similar articles hand-picked by GPT-4

    Senior Mindset Book

    Get promoted, earn a bigger salary, work for top companies

    Learn more

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️