Skip to content

[flag] warn for setState in render on initial mount - #35084

Open
rickhanlonii wants to merge 5 commits into
react:mainfrom
rickhanlonii:rh/set-state-mount-error
Open

[flag] warn for setState in render on initial mount#35084
rickhanlonii wants to merge 5 commits into
react:mainfrom
rickhanlonii:rh/set-state-mount-error

Conversation

@rickhanlonii

@rickhanloniirickhanlonii commented Nov 8, 2025

Copy link
Copy Markdown
Contributor

Overview

Add a feature flag disableSetStateInRenderOnMount to start experimenting with warning for setState in initial render.

Motivation

The main reason to start warning about this now is that supporting this prevents us from landing SSR optimizations such as inlining hooks and removing code to support updates during SSR. But this also indicates a performance issue in the app that can usually be easily fixed.

Pattern isn't useful

Usually, calling setState in initial render of a component is an accident, by forgetting to pass the initial value into useState():

functionComponent({value}){const[prev,setPrev]=useState();// 🚩 oops!if(prev!==value){setPrev(value);}}

For those use cases, the warning will fire and applying an easy fix to pass the inital state will give performance benefits since we won't need to immediately re-render a component on mount.

functionComponent({value}){const[prev,setPrev]=useState(value);// 😎if(prev!==value){setPrev(value);}}

Now this will setState in render on updates.

Future SSR improvements

If this pattern is fixed, we could compile the SSR bundle code from:

functionComponent({value}){const[prev,setPrev]=useState(value);if(prev!==value){setPrev(value);}constderivedValue=useMemo(()=>{returnvalue.filter(Boolean);},value);//...}

To:

functionComponent({value}){const[prev,setPrev]=[value,()=>{}];constderivedValue=value.filter(Boolean);//...}

This could be a huge speedup in SSR performance.

Experiment

To confirm how many cases fall into the easy fix, I'm rolling out a feature flag to test it in a large app to see what use cases are depending on this, and how difficult the fixes are.

Review

It's a pain to update the tests for Fiber and Fizz in different PRs because of the server integration tests.

Here's how the different warnings are implemented in separate commits:

@github-actionsgithub-actionsBot added the React Core Team Opened by a member of the React Core Team label Nov 8, 2025
@react-sizebot

react-sizebot commented Nov 8, 2025

Copy link
Copy Markdown

Comparing: 4842fbe...7820ad0

Critical size changes

Includes critical production bundles, as well as any change greater than 2%:

Name+/-BaseCurrent+/- gzipBase gzipCurrent gzip
oss-stable/react-dom/cjs/react-dom.production.js=6.84 kB6.84 kB=1.88 kB1.88 kB
oss-stable/react-dom/cjs/react-dom-client.production.js=611.08 kB611.08 kB=108.02 kB108.02 kB
oss-experimental/react-dom/cjs/react-dom.production.js=6.84 kB6.84 kB=1.88 kB1.88 kB
oss-experimental/react-dom/cjs/react-dom-client.production.js=677.02 kB677.02 kB=118.99 kB118.99 kB
facebook-www/ReactDOM-prod.classic.js=697.74 kB697.74 kB=122.68 kB122.68 kB
facebook-www/ReactDOM-prod.modern.js=688.05 kB688.05 kB=121.07 kB121.07 kB

Significant size changes

Includes any change greater than 0.2%:

Expand to show
Name+/-BaseCurrent+/- gzipBase gzipCurrent gzip
test_utils/ReactAllWarnings.js+0.35%67.70 kB67.94 kB+0.21%17.05 kB17.09 kB

Generated by 🚫 dangerJS against 7820ad0

@gaearon

Copy link
Copy Markdown
Collaborator

Maybe “during the initial render”? Set state “on mount” usually refers to doing it in an effect which isn’t what this seems to be about.

Also, “this behavior is deprecated” maybe could be “this is deprecated, pass the initial value to useState instead” or something like that so it’s clear how to fix it.

@rickhanlonii
rickhanloniiforce-pushed the rh/set-state-mount-error branch 2 times, most recently from 11f09d6 to 96509c5CompareNovember 11, 2025 20:56
@rickhanloniirickhanlonii changed the title [wip] warn for setState in render on initial mount[flag] warn for setState in render on initial mountNov 11, 2025
@rickhanlonii
rickhanlonii requested review from acdlite and sebmarkbage and removed request for sebmarkbageNovember 11, 2025 21:29
@rickhanlonii

Copy link
Copy Markdown
ContributorAuthor

Thanks @gaearon, message updated.

@rickhanlonii
rickhanloniiforce-pushed the rh/set-state-mount-error branch from d18a9ec to 48f80d6CompareFebruary 4, 2026 15:17
acdlite
acdlite previously approved these changes Feb 4, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA SignedReact Core TeamOpened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@rickhanlonii@react-sizebot@gaearon@acdlite