fix(react-stately): enable useControlledState early effect in React Native - #10550
fix(react-stately): enable useControlledState early effect in React Native#10550su-jin1425 wants to merge 2 commits into
Conversation
|
In Short just changed |
| expect(onChange).toHaveBeenLastCalledWith(3); | ||
| }); | ||
|
|
||
| it('fires onChange twice when parent resets value', () => { |
There was a problem hiding this comment.
what does this test have to do with anything?
There was a problem hiding this comment.
you didn't answer this question. Please see https://github.com/adobe/react-spectrum/blob/main/CONTRIBUTING.md#ai-assisted-contributions
There was a problem hiding this comment.
its a additional regression test i thought it was useful, but now i saw the added test does not directly exercise the document vs window environment condition that causes the React Native bug, so it does not provide meaningful regression coverage for this change.
| typeof document !== 'undefined' | ||
| ? (React['useInsertionEffect'] ?? React.useLayoutEffect) | ||
| : () => {}; | ||
| typeof window !== 'undefined' ? (React['useInsertionEffect'] ?? React.useLayoutEffect) : () => {}; |
There was a problem hiding this comment.
if I recall correctly, detecting SSR is best to check that document !== undefined and the check against window will fail against Deno
There's a check for React Native we could possibly add to this check
const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
typeof document !== 'undefined' || isReactNative
What do you think?
There was a problem hiding this comment.
what was your opinion on this question?
There was a problem hiding this comment.
The document check preserves existing SSR behavior, while the React Native check targets the actual issue. The tradeoff is relying on navigator.product, but this avoids changing behavior for runtimes like Deno. I think this is the safer, more targeted approach.
8ee60a8 to
68e76be
Compare
|
@snowystinger I have chnages as per your request , rereview once again and tell if you need any more changes. |
|
@snowystinger I think I still need more time to investigate so i will tell you when to review And also tell me that am I in correct approach or not. |
68e76be to
2804a1c
Compare
|
@snowystinger I'm Ready for Rereview |
snowystinger
left a comment
There was a problem hiding this comment.
Thanks, I think this is ok. Wish we had a place to test against React Native for stately.
| const isReactNative = typeof navigator !== 'undefined' && navigator.product === 'ReactNative'; | ||
| const useEarlyEffect: typeof React.useLayoutEffect = | ||
| typeof document !== 'undefined' | ||
| typeof document !== 'undefined' || isReactNative |
There was a problem hiding this comment.
instead of checking for this, we can use a check for versions below React 19 since this was to avoid a warning that occurs in those older versions
|
No need to request review every time, it's a lot of added noise. Team members will get to this when they can. Thanks. |
|
Ok. |
98ecbdb to
97ea7a6
Compare
Description
Closes #10512
Summary
useControlledStateuses an early synchronous effect to keep its internal value ref synchronized with controlled prop changes. The effect was previously enabled only whendocumentwas defined.In React Native,
documentis not available, causing the early effect to become a no-op. As a result, parent-driven controlled value changes could be ignored.Based on maintainer feedback, this PR introduces a specific check for React Native using
navigator.product === 'ReactNative'. This ensures the synchronous effect runs in both standard DOM environments and React Native, without usingwindowwhich would break Deno support.Changes
useControlledState.tsto usetypeof document !== 'undefined' || isReactNative.Why
React Native does not provide
document, so the previous check incorrectly disabled the synchronization effect. Checking forisReactNativeexplicitly avoids regressions in other DOM-less environments like Deno.Pull Request Checklist
CLAUDE.md.