@samitouri / QOS-React-1 / commits / b37e4b4e61

Clean up fastAddProperties and make it more correct (#29015)

## Summary This PR makes some fixes to the `fastAddProperties` function: - Use `if (!attributeConfig)` instead of `if (attributeConfig === undefined)` to account for `null`. - If a prop has an Object `attributeConfig` with a `diff` function defined on it, treat it as an atomic value to keep the semantics of `diffProperties`. ## How did you test this change? Build and run RNTester app.

Dmytro Rykun committed May 8, 2024 at 13:10 UTC b37e4b4e616d6d66c1cde9c0a4c2cbd866b0b582
1 file changed +34 -34
packages/react-native-renderer/src/ReactNativeAttributePayloadFabric.js
+34 -34
@@ -446,65 +446,65 @@ function diffProperties(
446 }
447
448 function fastAddProperties(
449 - updatePayload: null | Object,
450 - nextProps: Object,
449 + payload: null | Object,
450 + props: Object,
451 validAttributes: AttributeConfiguration,
452 ): null | Object {
453 let attributeConfig;
454 - let nextProp;
454 + let prop;
455
456 - for (const propKey in nextProps) {
457 - nextProp = nextProps[propKey];
456 + for (const propKey in props) {
457 + prop = props[propKey];
458
459 - if (nextProp === undefined) {
459 + if (prop === undefined) {
460 continue;
461 }
462
463 - attributeConfig = validAttributes[propKey];
463 + attributeConfig = ((validAttributes[propKey]: any): AttributeConfiguration);
464
465 - if (attributeConfig === undefined) {
465 + if (attributeConfig == null) {
466 continue;
467 }
468
469 - if (typeof nextProp === 'function') {
470 - nextProp = (true: any);
469 + let newValue;
470 +
471 + if (typeof prop === 'function') {
472 + // A function prop. It represents an event handler. Pass it to native as 'true'.
473 + newValue = true;
474 + } else if (typeof attributeConfig !== 'object') {
475 + // An atomic prop. Doesn't need to be flattened.
476 + newValue = prop;
477 + } else if (typeof attributeConfig.process === 'function') {
478 + // An atomic prop with custom processing.
479 + newValue = attributeConfig.process(prop);
480 + } else if (typeof attributeConfig.diff === 'function') {
481 + // An atomic prop with custom diffing. We don't do diffing here.
482 + newValue = prop;
483 }
484
473 - if (typeof attributeConfig !== 'object') {
474 - if (!updatePayload) {
475 - updatePayload = ({}: {[string]: $FlowFixMe});
485 + if (newValue !== undefined) {
486 + if (!payload) {
487 + payload = ({}: {[string]: $FlowFixMe});
488 }
477 - updatePayload[propKey] = nextProp;
489 + payload[propKey] = newValue;
490 continue;
491 }
492
481 - if (typeof attributeConfig.process === 'function') {
482 - if (!updatePayload) {
483 - updatePayload = ({}: {[string]: $FlowFixMe});
484 - }
485 - updatePayload[propKey] = attributeConfig.process(nextProp);
486 - continue;
487 - }
493 + // Not-atomic prop that needs to be flattened. Likely it's the 'style' prop.
494
489 - if (isArray(nextProp)) {
490 - for (let i = 0; i < nextProp.length; i++) {
491 - updatePayload = fastAddProperties(
492 - updatePayload,
493 - nextProp[i],
494 - ((attributeConfig: any): AttributeConfiguration),
495 - );
495 + // It can be an array.
496 + if (isArray(prop)) {
497 + for (let i = 0; i < prop.length; i++) {
498 + payload = fastAddProperties(payload, prop[i], attributeConfig);
499 }
500 continue;
501 }
502
500 - updatePayload = fastAddProperties(
501 - updatePayload,
502 - nextProp,
503 - ((attributeConfig: any): AttributeConfiguration),
504 - );
503 + // Or it can be an object.
504 + payload = fastAddProperties(payload, prop, attributeConfig);
505 }
506
507 - return updatePayload;
507 + return payload;
508 }
509
510 /**