Skip to content

[field] Prevent rerenders when control is uncontrolled#3820

Merged
atomiks merged 1 commit into
mui:masterfrom
atomiks:fix/field-uncontrolled-renders
Jan 22, 2026
Merged

[field] Prevent rerenders when control is uncontrolled#3820
atomiks merged 1 commit into
mui:masterfrom
atomiks:fix/field-uncontrolled-renders

Conversation

@atomiks

@atomiks atomiks commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

The useControlled/setValue wrapper was an unnecessary layer here

Fixes #3819

@atomiks atomiks added type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. component: field Changes related to the field component. labels Jan 21, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jan 21, 2026

Copy link
Copy Markdown
  • vite-css-base-ui-example

    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/react@3820
    
    pnpm add https://pkg.pr.new/mui/base-ui/@base-ui/utils@3820
    

commit: 33b4a22

@mui-bot

mui-bot commented Jan 21, 2026

Copy link
Copy Markdown

Bundle size report

Bundle Parsed size Gzip size
@base-ui/react ▼-30B(-0.01%) ▼-14B(-0.01%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@netlify

netlify Bot commented Jan 21, 2026

Copy link
Copy Markdown

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 33b4a22
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/6971518b22e7950008af2727
😎 Deploy Preview https://deploy-preview-3820--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@atomiks atomiks marked this pull request as ready for review January 21, 2026 22:25
@greptile-apps

greptile-apps Bot commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR optimizes performance for uncontrolled Field.Control inputs by removing unnecessary internal state updates on every keystroke. Previously, the component used useControlled hook's setter to track value changes even for uncontrolled inputs, causing the component to rerender on each keystroke.

The fix recognizes that for uncontrolled inputs, React doesn't need to track the value in state - the DOM element manages it via defaultValue. Now, only setDirty and setFilled state updates occur, which stabilize after the first keystroke (React's state setter bailout optimization prevents rerenders when setting the same value). This makes Base UI Input compatible with React Hook Form's performance expectations for uncontrolled inputs.

Key changes:

  • Removed useStableCallback wrapper around value setter
  • Eliminated unnecessary setValueUnwrapped calls for uncontrolled inputs
  • Simplified value handling: controlled inputs get value prop, uncontrolled get defaultValue
  • Added comprehensive test validating the rerender optimization

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is a focused performance optimization that simplifies the code by removing unnecessary state tracking for uncontrolled inputs. The implementation correctly leverages React's standard uncontrolled input pattern using defaultValue, and includes a comprehensive test that validates the performance improvement. The change does not affect controlled input behavior and maintains backward compatibility.
  • No files require special attention

Important Files Changed

Filename Overview
packages/react/src/field/control/FieldControl.tsx Removes unnecessary state tracking for uncontrolled inputs by eliminating the setValue wrapper and directly calling onValueChange, significantly reducing rerenders
packages/react/src/field/control/FieldControl.test.tsx Adds test verifying uncontrolled inputs don't cause unnecessary rerenders after the first change, validating the performance optimization

@atomiks atomiks merged commit 7412736 into mui:master Jan 22, 2026
25 checks passed
@atomiks atomiks deleted the fix/field-uncontrolled-renders branch January 22, 2026 07:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: field Changes related to the field component. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@base-ui/react/input (Field.Control) re-renders on every keystroke even when used uncontrolled (e.g. React Hook Form register)

3 participants