mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
disable event loop (#44169)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44169 ## Changelog: [General][Changed] Disable new event loop behavior when bridgeless (new architecture) is enabled. # What is the problem With event loop, specifically with `batchRenderingUpdatesInEventLoop`, prop change is not delivered to Android mounting layer if the prop change was initiated from state update inside of `useLayoutEffect`, `componentDidMount` or `componentDidUpdate`. Note this has to be a prop change affecting mounting layer directly, not something consumed by Yoga, e.g. background colour or border colour. This affects android only. Minimal repro : ``` import React, {useLayoutEffect, useState} from 'react'; import {Button, SafeAreaView, View} from 'react-native'; function Foo() { const [bgColor, setBgColor] = React.useState('red'); useLayoutEffect(() => { console.log('useLayoutEffect'); setBgColor('blue'); }, []); return ( <View style={{ backgroundColor: bgColor, width: '100%', height: '100%', }} /> ); } function RNTesterApp() { const [show, setShow] = useState(false); return ( <SafeAreaView> <Button title="Toggle" onPress={() => setShow(!show)} /> {show && <Foo />} </SafeAreaView> ); } export default RNTesterApp; ``` # The underlaying problem The problem is in batched rendering updates and how props are delivered to Android mounting layer. Here is a step by step what happens in the repro above: 1. React issues asks Fabric to create new shadow node A with background colour **red**. 2. Fabric asks Android to allocate a view for shadow node A with background colour **red**. 3. React commits tree **T1** and calls layout effects. Meanwhile Fabric waits, without trying to mount the tree **T1**, to prevent painting state that is about to be updated and prevent flickering. 4. React clones node A, changing the background colour to **blue** and commits the new tree **T2**. 5. Fabric, will now go ahead and mount the latest tree **T2**. While creating mount instructions, it will drop prop updates because it believes prop updates where delivered already as part of step 2. At first this might appear as a problem with view preallocation. But the underlaying trouble is that on Android, we currently have no way of knowing how to combine changesets from React into single folly::dynamic. Reviewed By: javache, cortinico Differential Revision: D56355863 fbshipit-source-id: f8616ee48e10fc10e129bb632c5d398842220d24
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ed7766cee9
commit
cf75d032d0
@@ -299,21 +299,7 @@
|
||||
|
||||
#pragma mark - Feature Flags
|
||||
|
||||
class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults {
|
||||
public:
|
||||
bool useModernRuntimeScheduler() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool enableMicrotasks() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool batchRenderingUpdatesInEventLoop() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults {};
|
||||
|
||||
- (void)_setUpFeatureFlags
|
||||
{
|
||||
|
||||
-6
@@ -49,12 +49,6 @@ public object DefaultNewArchitectureEntryPoint {
|
||||
if (bridgelessEnabled) {
|
||||
ReactNativeFeatureFlags.override(
|
||||
object : ReactNativeFeatureFlagsDefaults() {
|
||||
override fun useModernRuntimeScheduler(): Boolean = true
|
||||
|
||||
override fun enableMicrotasks(): Boolean = true
|
||||
|
||||
override fun batchRenderingUpdatesInEventLoop(): Boolean = true
|
||||
|
||||
override fun useNativeViewConfigsInBridgelessMode(): Boolean = fabricEnabled
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user