Skip to content

Commit 8dcdb70

Browse files
committed
Add useTraitHiddenOnIOS feature flag
Mirrors useTraitHiddenOnAndroid (#54112) on iOS so apps can opt out of the `Trait::Hidden` slice-skip optimization in sliceChildShadowNodeViewPairs. When the flag is `false`, Hidden subtrees remain in the mount slice and are hidden via `UIView.hidden = YES` through the existing UIView+ComponentViewProtocol path (D8460108, 2018) instead of being torn down via REMOVE + DELETE. Default `true` so iOS behaviour is unchanged for everyone who doesn't override it.
1 parent 795d902 commit 8dcdb70

22 files changed

Lines changed: 216 additions & 26 deletions

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<cd8218c8b8588f3317bf63ce8d608548>>
7+
* @generated SignedSource<<89627a52825452c8f6c0dd3725f61175>>
88
*/
99

1010
/**
@@ -546,6 +546,12 @@ public object ReactNativeFeatureFlags {
546546
@JvmStatic
547547
public fun useTraitHiddenOnAndroid(): Boolean = accessor.useTraitHiddenOnAndroid()
548548

549+
/**
550+
* Use Trait::hidden slice-skip on iOS. When false, Hidden subtrees stay mounted and hide via UIView.hidden = YES (the path in UIView+ComponentViewProtocol since 2018) instead of REMOVE + DELETE.
551+
*/
552+
@JvmStatic
553+
public fun useTraitHiddenOnIOS(): Boolean = accessor.useTraitHiddenOnIOS()
554+
549555
/**
550556
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
551557
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<4f9f5c1c46217ed6802abd5f786aac19>>
7+
* @generated SignedSource<<e2704fec486263b5f74ab909f9d2f533>>
88
*/
99

1010
/**
@@ -106,6 +106,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
106106
private var useNestedScrollViewAndroidCache: Boolean? = null
107107
private var useSharedAnimatedBackendCache: Boolean? = null
108108
private var useTraitHiddenOnAndroidCache: Boolean? = null
109+
private var useTraitHiddenOnIOSCache: Boolean? = null
109110
private var useTurboModuleInteropCache: Boolean? = null
110111
private var useTurboModulesCache: Boolean? = null
111112
private var useUnorderedMapInDifferentiatorCache: Boolean? = null
@@ -887,6 +888,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
887888
return cached
888889
}
889890

891+
override fun useTraitHiddenOnIOS(): Boolean {
892+
var cached = useTraitHiddenOnIOSCache
893+
if (cached == null) {
894+
cached = ReactNativeFeatureFlagsCxxInterop.useTraitHiddenOnIOS()
895+
useTraitHiddenOnIOSCache = cached
896+
}
897+
return cached
898+
}
899+
890900
override fun useTurboModuleInterop(): Boolean {
891901
var cached = useTurboModuleInteropCache
892902
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<8916e9f4a938a69ff175c806db9835d4>>
7+
* @generated SignedSource<<9a216ce4f720f39e338ba9eb40e3503d>>
88
*/
99

1010
/**
@@ -200,6 +200,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
200200

201201
@DoNotStrip @JvmStatic public external fun useTraitHiddenOnAndroid(): Boolean
202202

203+
@DoNotStrip @JvmStatic public external fun useTraitHiddenOnIOS(): Boolean
204+
203205
@DoNotStrip @JvmStatic public external fun useTurboModuleInterop(): Boolean
204206

205207
@DoNotStrip @JvmStatic public external fun useTurboModules(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<d2b14345bf627e35562530912b3aae1f>>
7+
* @generated SignedSource<<d047393d9b77ab6bdf610f272ec376cd>>
88
*/
99

1010
/**
@@ -195,6 +195,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
195195

196196
override fun useTraitHiddenOnAndroid(): Boolean = false
197197

198+
override fun useTraitHiddenOnIOS(): Boolean = true
199+
198200
override fun useTurboModuleInterop(): Boolean = false
199201

200202
override fun useTurboModules(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<cbe90c2bf8ba9d34804d97c31edfd31a>>
7+
* @generated SignedSource<<e23bcf89e2a15139f6a1511ebb7d6fc8>>
88
*/
99

1010
/**
@@ -110,6 +110,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
110110
private var useNestedScrollViewAndroidCache: Boolean? = null
111111
private var useSharedAnimatedBackendCache: Boolean? = null
112112
private var useTraitHiddenOnAndroidCache: Boolean? = null
113+
private var useTraitHiddenOnIOSCache: Boolean? = null
113114
private var useTurboModuleInteropCache: Boolean? = null
114115
private var useTurboModulesCache: Boolean? = null
115116
private var useUnorderedMapInDifferentiatorCache: Boolean? = null
@@ -977,6 +978,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
977978
return cached
978979
}
979980

981+
override fun useTraitHiddenOnIOS(): Boolean {
982+
var cached = useTraitHiddenOnIOSCache
983+
if (cached == null) {
984+
cached = currentProvider.useTraitHiddenOnIOS()
985+
accessedFeatureFlags.add("useTraitHiddenOnIOS")
986+
useTraitHiddenOnIOSCache = cached
987+
}
988+
return cached
989+
}
990+
980991
override fun useTurboModuleInterop(): Boolean {
981992
var cached = useTurboModuleInteropCache
982993
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<536a5156deea17740dd24782bf79feb4>>
7+
* @generated SignedSource<<4ba890681ce63a02ddcd443223515323>>
88
*/
99

1010
/**
@@ -195,6 +195,8 @@ public interface ReactNativeFeatureFlagsProvider {
195195

196196
@DoNotStrip public fun useTraitHiddenOnAndroid(): Boolean
197197

198+
@DoNotStrip public fun useTraitHiddenOnIOS(): Boolean
199+
198200
@DoNotStrip public fun useTurboModuleInterop(): Boolean
199201

200202
@DoNotStrip public fun useTurboModules(): Boolean

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b99eaffc2d11a08a6efe32b2e2732965>>
7+
* @generated SignedSource<<592d2f00a3b2ff81533cf74f27068819>>
88
*/
99

1010
/**
@@ -555,6 +555,12 @@ class ReactNativeFeatureFlagsJavaProvider
555555
return method(javaProvider_);
556556
}
557557

558+
bool useTraitHiddenOnIOS() override {
559+
static const auto method =
560+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useTraitHiddenOnIOS");
561+
return method(javaProvider_);
562+
}
563+
558564
bool useTurboModuleInterop() override {
559565
static const auto method =
560566
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useTurboModuleInterop");
@@ -1025,6 +1031,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useTraitHiddenOnAndroid(
10251031
return ReactNativeFeatureFlags::useTraitHiddenOnAndroid();
10261032
}
10271033

1034+
bool JReactNativeFeatureFlagsCxxInterop::useTraitHiddenOnIOS(
1035+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
1036+
return ReactNativeFeatureFlags::useTraitHiddenOnIOS();
1037+
}
1038+
10281039
bool JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop(
10291040
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
10301041
return ReactNativeFeatureFlags::useTurboModuleInterop();
@@ -1344,6 +1355,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
13441355
makeNativeMethod(
13451356
"useTraitHiddenOnAndroid",
13461357
JReactNativeFeatureFlagsCxxInterop::useTraitHiddenOnAndroid),
1358+
makeNativeMethod(
1359+
"useTraitHiddenOnIOS",
1360+
JReactNativeFeatureFlagsCxxInterop::useTraitHiddenOnIOS),
13471361
makeNativeMethod(
13481362
"useTurboModuleInterop",
13491363
JReactNativeFeatureFlagsCxxInterop::useTurboModuleInterop),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<4be32bad403baeca1a28f19ad181c42c>>
7+
* @generated SignedSource<<23eef56b233a38a30476600370621264>>
88
*/
99

1010
/**
@@ -288,6 +288,9 @@ class JReactNativeFeatureFlagsCxxInterop
288288
static bool useTraitHiddenOnAndroid(
289289
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
290290

291+
static bool useTraitHiddenOnIOS(
292+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
293+
291294
static bool useTurboModuleInterop(
292295
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
293296

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<b55a79c9f84947fa4c12b04f15cfeefb>>
7+
* @generated SignedSource<<05ffdb0ed4ce2b2f2eed475127ff170a>>
88
*/
99

1010
/**
@@ -370,6 +370,10 @@ bool ReactNativeFeatureFlags::useTraitHiddenOnAndroid() {
370370
return getAccessor().useTraitHiddenOnAndroid();
371371
}
372372

373+
bool ReactNativeFeatureFlags::useTraitHiddenOnIOS() {
374+
return getAccessor().useTraitHiddenOnIOS();
375+
}
376+
373377
bool ReactNativeFeatureFlags::useTurboModuleInterop() {
374378
return getAccessor().useTurboModuleInterop();
375379
}

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<8e9b09843bf4a0312b254559a975f612>>
7+
* @generated SignedSource<<21d1871f9323c4adc17695dcc141a60d>>
88
*/
99

1010
/**
@@ -469,6 +469,11 @@ class ReactNativeFeatureFlags {
469469
*/
470470
RN_EXPORT static bool useTraitHiddenOnAndroid();
471471

472+
/**
473+
* Use Trait::hidden slice-skip on iOS. When false, Hidden subtrees stay mounted and hide via UIView.hidden = YES (the path in UIView+ComponentViewProtocol since 2018) instead of REMOVE + DELETE.
474+
*/
475+
RN_EXPORT static bool useTraitHiddenOnIOS();
476+
472477
/**
473478
* In Bridgeless mode, should legacy NativeModules use the TurboModule system?
474479
*/

0 commit comments

Comments
 (0)