Skip to content

Commit e59a6be

Browse files
committed
fix(Fabric, iOS): soften the _props subclass assert in RCTViewComponentView.updateProps
Third-party Fabric component views that reset `_props` to base ViewProps in `prepareForRecycle` (observed with react-native-maps' `RNMapsGoogleMapView`) can receive `updateProps` with base `ViewProps` on the deep-link mount path (RN 0.88 + new arch). The current RCTAssert aborts the whole app on this diagnostic-only invariant (SIGABRT via NSInternalInconsistencyException), taking down production and dev sessions over a recoverable condition. The static_casts immediately below are to `const ViewProps &` and are valid for base ViewProps, so mounting can continue safely. This changes the assert to an RCTLogError so the condition is still visible in logs while the app survives. Repro: expo-router deep link directly to a screen containing a Google Map while a recycled map view is being re-prepared; app aborts with NSInternalInconsistencyException `...must setup `_props`...` (crash logs show -[RCTViewComponentView updateProps:oldProps:]). Changelog: [iOS] [Fixed] Soften the _props subclass assert in RCTViewComponentView.updateProps to an error log
1 parent 46d0041 commit e59a6be

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

‎packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,21 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &
337337

338338
#ifndef NS_BLOCK_ASSERTIONS
339339
auto propsRawPtr = _props.get();
340-
RCTAssert(
341-
propsRawPtr &&
342-
([self class] == [RCTViewComponentView class] ||
343-
typeid(*propsRawPtr).hash_code() != typeid(const ViewProps).hash_code()),
344-
@"`RCTViewComponentView` subclasses (and `%@` particularly) must setup `_props`"
345-
" instance variable with a default value in the constructor.",
346-
NSStringFromClass([self class]));
340+
// SOFTENED: third-party component views that reset _props to base ViewProps
341+
// in prepareForRecycle (observed: react-native-maps RNMapsGoogleMapView) can
342+
// receive updateProps with base ViewProps on the deep-link mount path
343+
// (RN 0.88 + new arch). Aborting there takes the whole app down on a
344+
// diagnostic-only invariant, and the static_casts below are valid for base
345+
// ViewProps anyway. Log instead of abort.
346+
if (!(propsRawPtr &&
347+
([self class] == [RCTViewComponentView class] ||
348+
typeid(*propsRawPtr).hash_code() != typeid(const ViewProps).hash_code()))) {
349+
RCTLogError(
350+
@"`RCTViewComponentView` subclass `%@` received updateProps with base "
351+
"ViewProps (_props not set by the subclass constructor or recycled). "
352+
"Continuing with base props.",
353+
NSStringFromClass([self class]));
354+
}
347355
#endif
348356

349357
const auto &oldViewProps = static_cast<const ViewProps &>(*_props);

0 commit comments

Comments
 (0)