Summary
The Checkbox component currently uses a useLayoutEffect to imperatively set the DOM .indeterminate property on the underlying <input> element. While this works, it can be replaced with a ref callback, which runs synchronously during commit (same timing guarantees as useLayoutEffect) without registering a separate effect.
Current behavior
useLayoutEffect(() => {
if (checkboxRef.current) {
checkboxRef.current.indeterminate = indeterminate || false
}
}, [indeterminate, checked, checkboxRef])
Proposed change
Replace with a ref callback that sets .indeterminate inline:
const setIndeterminate = React.useCallback(
(node: HTMLInputElement | null) => {
if (node) {
node.indeterminate = indeterminate || false
}
},
[indeterminate, checked],
)
// merge with the forwarded ref
const mergedRef = useMergedRef(checkboxRef, setIndeterminate)
Additional cleanup
The useEffect that sets aria-checked can also be replaced with an inline JSX attribute:
'aria-checked': indeterminate ? 'mixed' : undefined
This avoids an unnecessary effect per Checkbox instance.
Motivation
- Ref callbacks are the idiomatic React pattern for imperative DOM properties with no HTML attribute equivalent
- Eliminates a layout effect per Checkbox render, reducing React commit phase work
- Minor but measurable improvement in pages that render many checkboxes (e.g., list views with bulk selection)
References
Summary
The
Checkboxcomponent currently uses auseLayoutEffectto imperatively set the DOM.indeterminateproperty on the underlying<input>element. While this works, it can be replaced with a ref callback, which runs synchronously during commit (same timing guarantees asuseLayoutEffect) without registering a separate effect.Current behavior
Proposed change
Replace with a ref callback that sets
.indeterminateinline:Additional cleanup
The
useEffectthat setsaria-checkedcan also be replaced with an inline JSX attribute:This avoids an unnecessary effect per Checkbox instance.
Motivation
References
Checkbox.tsx