Fix fastAddProperties to properly nullify style props (#30334)
## Summary This PR fixes the `fastAddProperties` function. Now it nullifies a prop if it was defined in one of the items of a style array, but then set to `undefined` or `null` in one of the subsequent items. E.g. `style: [{top: 0}, {top: undefined}]` should evaluate to `{top: null}`. Also added a test case for that. ## How did you test this change? ``` yarn test packages/react-native-renderer -r=xplat --variant=false yarn test packages/react-native-renderer -r=xplat --variant=true yarn flow native ```
Dmytro Rykun committed
Jul 15, 2024 at 17:32 UTC
f510ece86d4621d3b0faf9fe59d850f7807dbb16
2 files changed
+18
-6
packages/react-native-renderer/src/ReactNativeAttributePayloadFabric.js
+8
-5
@@ -464,10 +464,6 @@ function fastAddProperties(
464
for (const propKey in props) {
465
const prop = props[propKey];
466
467
- if (prop === undefined) {
468
- continue;
469
- }
470
-
467
const attributeConfig = ((validAttributes[
468
propKey
469
]: any): AttributeConfiguration);
@@ -478,7 +474,14 @@ function fastAddProperties(
474
475
let newValue;
476
481
- if (typeof prop === 'function') {
477
+ if (prop === undefined) {
478
+ // Discard the prop if it was previously defined.
479
+ if (payload && payload[propKey] !== undefined) {
480
+ newValue = null;
481
+ } else {
482
+ continue;
483
+ }
484
+ } else if (typeof prop === 'function') {
485
// A function prop. It represents an event handler. Pass it to native as 'true'.
486
newValue = true;
487
} else if (typeof attributeConfig !== 'object') {
packages/react-native-renderer/src/__tests__/ReactNativeAttributePayloadFabric-test.internal.js
+10
-1
@@ -60,7 +60,16 @@ describe('ReactNativeAttributePayloadFabric.create', () => {
60
});
61
});
62
63
- it('should ignore fields that are set to undefined', () => {
63
+ it('should nullify previously defined style prop that is subsequently set to null or undefined', () => {
64
+ expect(
65
+ create({style: [{a: 0}, {a: undefined}]}, {style: {a: true}}),
66
+ ).toEqual({a: null});
67
+ expect(create({style: [{a: 0}, {a: null}]}, {style: {a: true}})).toEqual({
68
+ a: null,
69
+ });
70
+ });
71
+
72
+ it('should ignore non-style fields that are set to undefined', () => {
73
expect(create({}, {a: true})).toEqual(null);
74
expect(create({a: undefined}, {a: true})).toEqual(null);
75
expect(create({a: undefined, b: undefined}, {a: true, b: true})).toEqual(