Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Switch causing RetryableMountingLayerException #32602

Closed
wants to merge 2 commits into from

Conversation

jonathanmos
Copy link
Contributor

@jonathanmos jonathanmos commented Nov 16, 2021

Summary

Added a null check to native.value in Switch to fix regression from RN 66 -> stuck operation in mViewCommandOperations list in Android Release on initial layout of a screen with Switch component. If approved, please incorporate this fix into an RN 66 release.

Changelog

[Android][Fixed] - Added a null check to native.value in Switch to fix #32594

Test Plan

To reproduce, put a log in UIViewOperationQueue in dispatchViewUpdates you can see that the RetryableMountingException is no longer thrown for a screen with the Switch component on Android Release. As a result, mViewCommandOperations no longer has a stuck operation on initial layout.

Summary:
Changelog:
Change useLayoutEffect to useEffect to fix facebook#32594 - stuck operation in mViewCommandOperations list in Android Release
@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Nov 16, 2021
@react-native-bot react-native-bot added Bug Platform: Android Android applications. labels Nov 16, 2021
@analysis-bot
Copy link

analysis-bot commented Nov 16, 2021

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: 05b4570
Branch: main

@analysis-bot
Copy link

analysis-bot commented Nov 16, 2021

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 8,477,042 +288,693
android hermes armeabi-v7a 7,776,544 -11,931
android hermes x86 8,945,903 +387,608
android hermes x86_64 8,890,002 +378,670
android jsc arm64-v8a 9,791,895 -65,574
android jsc armeabi-v7a 8,752,623 -89,506
android jsc x86 9,740,722 -82,791
android jsc x86_64 10,341,576 -79,108

Base commit: 05b4570
Branch: main

Copy link
Contributor

@lunaleaps lunaleaps left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the issue, you mention that we attempt to setNativeValue on initial render but wouldn't nativeSwitchRef.current be null in this case?

I believe that's why we have the check there to avoid the case of the native view not being rendered yet. If this isn't the appropriate check, then maybe we need to update it.

@lunaleaps
Copy link
Contributor

lunaleaps commented Dec 6, 2021

For more context, this was part of a Switch refactor and this logic used to live in a componentDidUpdate (

this._nativeSwitchRef.setNativeProps
). I believe these changes should still occur in a useLayoutEffect as this behavior we're trying to do is keep the JS and native value in sync but maybe we need to also check if nativeValue is set.

Although, forgive me if I'm mis-remembering, shouldn't the native ref only be set when the native view has been rendered?

@d4vidi
Copy link
Contributor

d4vidi commented Dec 20, 2021

@jonathanmos ping?

@jonathanmos
Copy link
Contributor Author

@lunaleaps I'd like to revive this pr and hopefully we can bring it to a conclusion.

You suggested in your comments adding a check for whether native.value was set. I've tried adding such a check to shouldUpdateNativeSwitch and it does solve the issue, but I've hesitated to push it as a fix as i noticed that after this change shouldUpdateNativeSwitch seems to always return false (value is always equal to native.value) and so setNativeValue is not being called. I think I'm not understanding completely in what situation these values are both set but different. Do you know what steps I can use to simulate such a situation in a test to ensure that everything works as expected?

@jonathanmos
Copy link
Contributor Author

jonathanmos commented Jan 25, 2022

Regarding the nativeref being set only on render, I'm unsure exactly what is going on here. The nativeref is undoubtedly set when the call to setnativevalue is made, but nevertheless causes a retryableMountingException on the initial render

@asafkorem
Copy link
Contributor

Hi @lunaleaps 👋🏼
We will be very grateful to reach a solution soon, as this stuck operation affects Detox tests directly with synchronization issues and fails tests of screens that involves switch components unless a workaround is used. 🙏🏼

@lunaleaps
Copy link
Contributor

jonathanmos

Hmm for coming up with a case where native might be out of sync with JS, I think is an edge case. I could see something like dynamically toggling disabled perhaps that will get the native value and JS value out of sync or a very quick succession of JS updates? Generally that useLayoutEffect logic shouldn't be firing as JS and native values should mostly be in sync

Are you seeing other issues when adding a null check for nativeSwitchRef on this line?

@jonathanmos
Copy link
Contributor Author

@lunaleaps In the tests that I've run, out of the variables in useLayoutEffect, only native.value is null on initial render of the component (although this is unconnected to whether the RetryableMountingLayerException is thrown as sometimes it is and sometimes not). Adding a null check for native.value in this line prevents useLayoutEffect from executing logic on the initial render. This 'solves' the issue by avoiding inserting the problematic operation into the queue.

I've tried rapid toggling of disabled state for the switch, as well as sending many js operations, but was unable to produce a situation where sync was lost.

@facebook-github-bot
Copy link
Contributor

@lunaleaps has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@lunaleaps
Copy link
Contributor

@jonathanmos Can we update the changelog summary of this change as well? Thanks!

@jonathanmos
Copy link
Contributor Author

@lunaleaps I've updated the changelog for the issue

@facebook-github-bot
Copy link
Contributor

@lunaleaps has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@lunaleaps
Copy link
Contributor

Oh actually thinking about this again, I think the case to test this is if we hardcode the JS value to be some constant value -- then we want to ignore any attempts of native to toggle the switch. Let me try this case out

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @jonathanmos in 8d50bf1.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Feb 25, 2022
ShikaSD pushed a commit that referenced this pull request Mar 16, 2022
Summary:
Added a null check to native.value in Switch to fix regression from RN 66 -> stuck operation in mViewCommandOperations list in Android Release on initial layout of a screen with Switch component. If approved, please incorporate this fix into an RN 66 release.

## Changelog
[Android][Fixed] - Added a null check to native.value in Switch to fix #32594

Pull Request resolved: #32602

Test Plan: To reproduce, put a log in UIViewOperationQueue in dispatchViewUpdates you can see that the RetryableMountingException is no longer thrown for a screen with the Switch component on Android Release. As a result, mViewCommandOperations no longer has a stuck operation on initial layout.

Reviewed By: charlesbdudley

Differential Revision: D34397788

Pulled By: lunaleaps

fbshipit-source-id: 1cee3516fb987942dfa50ad1f2d11c965a947f05
ShikaSD pushed a commit that referenced this pull request Mar 18, 2022
Summary:
Added a null check to native.value in Switch to fix regression from RN 66 -> stuck operation in mViewCommandOperations list in Android Release on initial layout of a screen with Switch component. If approved, please incorporate this fix into an RN 66 release.

## Changelog
[Android][Fixed] - Added a null check to native.value in Switch to fix #32594

Pull Request resolved: #32602

Test Plan: To reproduce, put a log in UIViewOperationQueue in dispatchViewUpdates you can see that the RetryableMountingException is no longer thrown for a screen with the Switch component on Android Release. As a result, mViewCommandOperations no longer has a stuck operation on initial layout.

Reviewed By: charlesbdudley

Differential Revision: D34397788

Pulled By: lunaleaps

fbshipit-source-id: 1cee3516fb987942dfa50ad1f2d11c965a947f05
Saadnajmi pushed a commit to Saadnajmi/react-native-macos that referenced this pull request Jan 15, 2023
Summary:
Added a null check to native.value in Switch to fix regression from RN 66 -> stuck operation in mViewCommandOperations list in Android Release on initial layout of a screen with Switch component. If approved, please incorporate this fix into an RN 66 release.

## Changelog
[Android][Fixed] - Added a null check to native.value in Switch to fix facebook#32594

Pull Request resolved: facebook#32602

Test Plan: To reproduce, put a log in UIViewOperationQueue in dispatchViewUpdates you can see that the RetryableMountingException is no longer thrown for a screen with the Switch component on Android Release. As a result, mViewCommandOperations no longer has a stuck operation on initial layout.

Reviewed By: charlesbdudley

Differential Revision: D34397788

Pulled By: lunaleaps

fbshipit-source-id: 1cee3516fb987942dfa50ad1f2d11c965a947f05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Needs: React Native Team Attention Platform: Android Android applications. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RN 0.66 Switch causes a stuck operation in mViewCommandOperations
8 participants