@@ -1378,7 +1378,6 @@ function handleProps(
13781378 container : ClientContainer
13791379) : boolean {
13801380 let shouldRender = false ;
1381- let propsAreDifferent = false ;
13821381 if ( vNodeProps ) {
13831382 const effects = vNodeProps [ _PROPS_HANDLER ] . $effects$ ;
13841383 const constPropsDifferent = handleChangedProps (
@@ -1388,33 +1387,24 @@ function handleProps(
13881387 container ,
13891388 false
13901389 ) ;
1391- propsAreDifferent = constPropsDifferent ;
13921390 shouldRender ||= constPropsDifferent ;
13931391 if ( effects && effects . size > 0 ) {
1394- const varPropsDifferent = handleChangedProps (
1392+ handleChangedProps (
13951393 jsxProps [ _VAR_PROPS ] ,
13961394 vNodeProps [ _VAR_PROPS ] ,
13971395 vNodeProps [ _PROPS_HANDLER ] ,
1398- container
1396+ container ,
1397+ true
13991398 ) ;
1400-
1401- propsAreDifferent ||= varPropsDifferent ;
14021399 // don't mark as should render, effects will take care of it
1403- // shouldRender ||= varPropsDifferent;
1404- }
1405- }
1406-
1407- if ( propsAreDifferent ) {
1408- if ( vNodeProps ) {
1409- // Reuse the same props instance, qrls can use the current props instance
1410- // as a capture ref, so we can't change it.
1411- vNodeProps [ _OWNER ] = ( jsxProps as PropsProxy ) [ _OWNER ] ;
1412- } else if ( jsxProps ) {
1413- // If there is no props instance, create a new one.
1414- // We can do this because we are not using the props instance for anything else.
1415- vnode_setProp ( host as VirtualVNode , ELEMENT_PROPS , jsxProps ) ;
1416- vNodeProps = jsxProps ;
14171400 }
1401+ // Update the owner after all props have been synced
1402+ vNodeProps [ _OWNER ] = ( jsxProps as PropsProxy ) [ _OWNER ] ;
1403+ } else if ( jsxProps ) {
1404+ // If there is no props instance, create a new one.
1405+ // We can do this because we are not using the props instance for anything else.
1406+ vnode_setProp ( host as VirtualVNode , ELEMENT_PROPS , jsxProps ) ;
1407+ vNodeProps = jsxProps ;
14181408 }
14191409 return shouldRender ;
14201410}
@@ -1426,51 +1416,49 @@ function handleChangedProps(
14261416 container : ClientContainer ,
14271417 triggerEffects : boolean = true
14281418) : boolean {
1429- const srcEmpty = isPropsEmpty ( src ) ;
1430- const dstEmpty = isPropsEmpty ( dst ) ;
1431-
1432- if ( srcEmpty && dstEmpty ) {
1419+ if ( isPropsEmpty ( src ) && isPropsEmpty ( dst ) ) {
14331420 return false ;
14341421 }
14351422
1436- if ( srcEmpty || dstEmpty ) {
1437- return true ;
1438- }
1439-
1440- const srcKeys = Object . keys ( src ! ) ;
1441- const dstKeys = Object . keys ( dst ! ) ;
1442-
1443- let srcLen = srcKeys . length ;
1444- let dstLen = dstKeys . length ;
1445- if ( 'children' in src ! ) {
1446- srcLen -- ;
1447- }
1448- if ( QBackRefs in src ! ) {
1449- srcLen -- ;
1450- }
1451- if ( 'children' in dst ! ) {
1452- dstLen -- ;
1453- }
1454- if ( QBackRefs in dst ! ) {
1455- dstLen -- ;
1456- }
1423+ propsHandler . $container$ = container ;
1424+ let changed = false ;
14571425
1458- if ( srcLen !== dstLen ) {
1459- return true ;
1426+ // Update changed/added props from src
1427+ if ( src ) {
1428+ for ( const key in src ) {
1429+ if ( key === 'children' || key === QBackRefs ) {
1430+ continue ;
1431+ }
1432+ if ( ! dst || src [ key ] !== dst [ key ] ) {
1433+ changed = true ;
1434+ if ( triggerEffects ) {
1435+ if ( dst ) {
1436+ // Update the value in dst BEFORE triggering effects
1437+ // so effects see the new value
1438+ // Note: Value is not triggering effects, because we are modyfing direct VAR_PROPS object
1439+ dst [ key ] = src [ key ] ;
1440+ }
1441+ triggerPropsProxyEffect ( propsHandler , key ) ;
1442+ } else {
1443+ // Early return for const props (no effects)
1444+ return true ;
1445+ }
1446+ }
1447+ }
14601448 }
14611449
1462- let changed = false ;
1463- propsHandler . $container$ = container ;
1464- for ( const key of srcKeys ) {
1465- if ( key === 'children' || key === QBackRefs ) {
1466- continue ;
1467- }
1468- if ( ! Object . prototype . hasOwnProperty . call ( dst , key ) || src ! [ key ] !== dst ! [ key ] ) {
1469- changed = true ;
1470- if ( triggerEffects ) {
1471- triggerPropsProxyEffect ( propsHandler , key ) ;
1472- } else {
1473- return true ;
1450+ // Remove props that are in dst but not in src
1451+ if ( dst ) {
1452+ for ( const key in dst ) {
1453+ if ( key === 'children' || key === QBackRefs ) {
1454+ continue ;
1455+ }
1456+ if ( ! src || ! ( key in src ) ) {
1457+ changed = true ;
1458+ if ( triggerEffects ) {
1459+ delete dst [ key ] ;
1460+ triggerPropsProxyEffect ( propsHandler , key ) ;
1461+ }
14741462 }
14751463 }
14761464 }
0 commit comments