Skip to content

Commit bc005aa

Browse files
authored
fix(android): fix MaskView broken when enabling RN props 2.0 (#2948)
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please follow the template so that the reviewers can easily understand what the code changes affect --> # Summary On android when enabling props 2.0 diffing in react-native: ```kt override fun enablePropsUpdateReconciliationAndroid(): Boolean = true override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = true override fun enableExclusivePropsUpdateAndroid(): Boolean = true ``` the mounting layer will use `Props::getDiffProps()` to figure out what props to supply to the native views: https://github.com/facebook/react-native/blob/91702e50fe077ae73ab152da18719d6df98cb71f/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.cpp#L314-L318 In RN-SVGs codegen specs we specify for mask the following: https://github.com/software-mansion/react-native-svg/blob/52369e1a5a7cbc3e21e32adecba4839c8bf56e5b/src/fabric/MaskNativeComponent.ts#L77-L79 which will generate: <img width="588" height="259" alt="Screenshot 2026-05-07 at 15 29 26" src="https://github.com/user-attachments/assets/9f156262-96cb-43f8-b48f-d02458fad8dd" /> So you see that we specified `maskType` as optional, but on the c++ level the prop got as default value of `0`. > There is a way to change this in codegen setting [generateOptionalProperties](react/react-native#54724) as option. However, for `Int32` values [its broken right now unfortunately](react/react-native#55315). [Making it also optional in the c++ props would've been the better fix imo] Now, the problem is that in JS we set the default `maskType={0}`: https://github.com/software-mansion/react-native-svg/blob/52369e1a5a7cbc3e21e32adecba4839c8bf56e5b/src/elements/Mask.tsx#L61 https://github.com/software-mansion/react-native-svg/blob/52369e1a5a7cbc3e21e32adecba4839c8bf56e5b/src/lib/maskType.ts#L1-L3 _However,_ now when the mounting layer calls `getDiffProps` it will compare our passed prop value of `maskType={0}` with the default value `int maskType{0}`, and there will be no diff …: <img width="726" height="253" alt="Screenshot 2026-05-07 at 15 36 57" src="https://github.com/user-attachments/assets/e82f86a7-7430-4114-beb7-0493adf3fb1a" /> … so as there is no diff, the prop will never be dispatched to our native component hence `setMaskType` will never be called: https://github.com/software-mansion/react-native-svg/blob/51defd73d33a367c85b68b4007431347f049706b/android/src/main/java/com/horcrux/svg/MaskView.java#L93-L104 Which basically breaks the mask from working! In general we need to make sure that assumed defaults (ie. maskType default value 0) are reflected in the native component implementation, and we shouldn't rely on prop setter functions being called for default values. Hence my fix here is to simply set the default value in the native view :\) ## Test Plan ### What's required for testing (prerequisites)? Try to set the feature flags i mentioned and then observe the issues with mask component ### What are the steps to reproduce (after prerequisites)? ^ ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ❌ | | MacOS | ❌ | | Android | ✅ | | Web | ❌ | ## Checklist <!-- Check completed item, when applicable, via: [X] --> - [x] I have tested this on a device and a simulator - [x] I added documentation in `README.md` - [x] I updated the typed files (typescript) - [x] I added a test for the API in the `__tests__` folder
1 parent 21c4783 commit bc005aa

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

android/src/main/java/com/horcrux/svg/MaskView.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ class MaskView extends GroupView {
2222

2323
// TODO implement proper support for units
2424
@SuppressWarnings({"FieldCanBeLocal", "unused"})
25-
private Brush.BrushUnits mMaskUnits;
25+
private Brush.BrushUnits mMaskUnits = Brush.BrushUnits.OBJECT_BOUNDING_BOX;
2626

2727
@SuppressWarnings({"FieldCanBeLocal", "unused"})
2828
private Brush.BrushUnits mMaskContentUnits;
2929

30-
MaskType mMaskType;
30+
MaskType mMaskType = MaskType.LUMINANCE;
3131

3232
enum MaskType {
3333
LUMINANCE,

0 commit comments

Comments
 (0)