function _updateDOMProperties(lastProps, nextProps, transaction) {
	    var propKey;
	    var styleName;
	    var styleUpdates;
	    for (propKey in lastProps) {
	      if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
	        continue;
	      }
	      if (propKey === STYLE) {
	        var lastStyle = this._previousStyleCopy;
	        for (styleName in lastStyle) {
	          if (lastStyle.hasOwnProperty(styleName)) {
	            styleUpdates = styleUpdates || {};
	            styleUpdates[styleName] = '';
	          }
	        }
	        this._previousStyleCopy = null;
	      } else if (registrationNameModules.hasOwnProperty(propKey)) {
	        if (lastProps[propKey]) {
	          // Only call deleteListener if there was a listener previously or
	          // else willDeleteListener gets called when there wasn't actually a
	          // listener (e.g., onClick={null})
	          deleteListener(this, propKey);
	        }
	      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
	        DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey);
	      }
	    }
	    for (propKey in nextProps) {
	      var nextProp = nextProps[propKey];
	      var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined;
	      if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
	        continue;
	      }
	      if (propKey === STYLE) {
	        if (nextProp) {
	          if (process.env.NODE_ENV !== 'production') {
	            checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
	            this._previousStyle = nextProp;
	          }
	          nextProp = this._previousStyleCopy = _assign({}, nextProp);
	        } else {
	          this._previousStyleCopy = null;
	        }
	        if (lastProp) {
	          // Unset styles on `lastProp` but not on `nextProp`.
	          for (styleName in lastProp) {
	            if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
	              styleUpdates = styleUpdates || {};
	              styleUpdates[styleName] = '';
	            }
	          }
	          // Update styles that changed since `lastProp`.
	          for (styleName in nextProp) {
	            if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
	              styleUpdates = styleUpdates || {};
	              styleUpdates[styleName] = nextProp[styleName];
	            }
	          }
	        } else {
	          // Relies on `updateStylesByID` not mutating `styleUpdates`.
	          styleUpdates = nextProp;
	        }
	      } else if (registrationNameModules.hasOwnProperty(propKey)) {
	        if (nextProp) {
	          enqueuePutListener(this, propKey, nextProp, transaction);
	        } else if (lastProp) {
	          deleteListener(this, propKey);
	        }
	      } else if (isCustomComponent(this._tag, nextProps)) {
	        if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
	          DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp);
	        }
	      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
	        var node = getNode(this);
	        // If we're updating to null or undefined, we should remove the property
	        // from the DOM node instead of inadvertently setting to a string. This
	        // brings us in line with the same behavior we have on initial render.
	        if (nextProp != null) {
	          DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);
	        } else {
	          DOMPropertyOperations.deleteValueForProperty(node, propKey);
	        }
	      }
	    }
	    if (styleUpdates) {
	      CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this);
	    }
	  }
/**
	   * Reconciles the properties by detecting differences in property values and
	   * updating the DOM as necessary. This function is probably the single most
	   * critical path for performance optimization.
	   *
	   * TODO: Benchmark whether checking for changed values in memory actually
	   *       improves performance (especially statically positioned elements).
	   * TODO: Benchmark the effects of putting this at the top since 99% of props
	   *       do not change for a given reconciliation.
	   * TODO: Benchmark areas that can be improved with caching.
	   *
	   * @private
	   * @param {object} lastProps
	   * @param {object} nextProps
	   * @param {?DOMElement} node
	   */
Reconciles the properties by detecting differences in property values and
updating the DOM as necessary. This function is probably the single most
critical path for performance optimization.

Benchmark whether checking for changed values in memory actually
improves performance (especially statically positioned elements).
TODO: Benchmark the effects of putting this at the top since 99% of props
do not change for a given reconciliation.
TODO: Benchmark areas that can be improved with caching.

@private
@param {object} lastProps
@param {object} nextProps
@param {?DOMElement} node
Reconciles the properties by detecting differences in property values and updating the DOM as necessary . This function is probably the single most critical path for performance optimization . Benchmark whether checking for changed values in memory actually improves performance ( especially statically positioned elements ) . TODO : Benchmark the effects of putting this at the top since 99% of props do not change for a given reconciliation . TODO : Benchmark areas that can be improved with caching . @private @param { object } lastProps @param { object } nextProps @param { ?DOMElement } node
function _updateDOMProperties(lastProps, nextProps, transaction) {
	    var propKey;
	    var styleName;
	    var styleUpdates;
	    for (propKey in lastProps) {
	      if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
	        continue;
	      }
	      if (propKey === STYLE) {
	        var lastStyle = this._previousStyleCopy;
	        for (styleName in lastStyle) {
	          if (lastStyle.hasOwnProperty(styleName)) {
	            styleUpdates = styleUpdates || {};
	            styleUpdates[styleName] = '';
	          }
	        }
	        this._previousStyleCopy = null;
	      } else if (registrationNameModules.hasOwnProperty(propKey)) {
	        if (lastProps[propKey]) {
	          deleteListener(this, propKey);
	        }
	      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
	        DOMPropertyOperations.deleteValueForProperty(getNode(this), propKey);
	      }
	    }
	    for (propKey in nextProps) {
	      var nextProp = nextProps[propKey];
	      var lastProp = propKey === STYLE ? this._previousStyleCopy : lastProps != null ? lastProps[propKey] : undefined;
	      if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
	        continue;
	      }
	      if (propKey === STYLE) {
	        if (nextProp) {
	          if (process.env.NODE_ENV !== 'production') {
	            checkAndWarnForMutatedStyle(this._previousStyleCopy, this._previousStyle, this);
	            this._previousStyle = nextProp;
	          }
	          nextProp = this._previousStyleCopy = _assign({}, nextProp);
	        } else {
	          this._previousStyleCopy = null;
	        }
	        if (lastProp) {
	          for (styleName in lastProp) {
	            if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
	              styleUpdates = styleUpdates || {};
	              styleUpdates[styleName] = '';
	            }
	          }
	          for (styleName in nextProp) {
	            if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
	              styleUpdates = styleUpdates || {};
	              styleUpdates[styleName] = nextProp[styleName];
	            }
	          }
	        } else {
	          styleUpdates = nextProp;
	        }
	      } else if (registrationNameModules.hasOwnProperty(propKey)) {
	        if (nextProp) {
	          enqueuePutListener(this, propKey, nextProp, transaction);
	        } else if (lastProp) {
	          deleteListener(this, propKey);
	        }
	      } else if (isCustomComponent(this._tag, nextProps)) {
	        if (!RESERVED_PROPS.hasOwnProperty(propKey)) {
	          DOMPropertyOperations.setValueForAttribute(getNode(this), propKey, nextProp);
	        }
	      } else if (DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) {
	        var node = getNode(this);
	        if (nextProp != null) {
	          DOMPropertyOperations.setValueForProperty(node, propKey, nextProp);
	        } else {
	          DOMPropertyOperations.deleteValueForProperty(node, propKey);
	        }
	      }
	    }
	    if (styleUpdates) {
	      CSSPropertyOperations.setValueForStyles(getNode(this), styleUpdates, this);
	    }
	  }
function _updateDOMProperties ( lastProps , nextProps , transaction ) { var propKey ; var styleName ; var styleUpdates ; for ( propKey in lastProps ) { if ( nextProps . hasOwnProperty ( propKey ) || ! lastProps . hasOwnProperty ( propKey ) || lastProps [ propKey ] == null ) { continue ; } if ( propKey === STYLE ) { var lastStyle = this . _previousStyleCopy ; for ( styleName in lastStyle ) { if ( lastStyle . hasOwnProperty ( styleName ) ) { styleUpdates = styleUpdates || { } ; styleUpdates [ styleName ] = '' ; } } this . _previousStyleCopy = null ; } else if ( registrationNameModules . hasOwnProperty ( propKey ) ) { if ( lastProps [ propKey ] ) { deleteListener ( this , propKey ) ; } } else if ( DOMProperty . properties [ propKey ] || DOMProperty . isCustomAttribute ( propKey ) ) { DOMPropertyOperations . deleteValueForProperty ( getNode ( this ) , propKey ) ; } } for ( propKey in nextProps ) { var nextProp = nextProps [ propKey ] ; var lastProp = propKey === STYLE ? this . _previousStyleCopy : lastProps != null ? lastProps [ propKey ] : undefined ; if ( ! nextProps . hasOwnProperty ( propKey ) || nextProp === lastProp || nextProp == null && lastProp == null ) { continue ; } if ( propKey === STYLE ) { if ( nextProp ) { if ( process . env . NODE_ENV !== 'production' ) { checkAndWarnForMutatedStyle ( this . _previousStyleCopy , this . _previousStyle , this ) ; this . _previousStyle = nextProp ; } nextProp = this . _previousStyleCopy = _assign ( { } , nextProp ) ; } else { this . _previousStyleCopy = null ; } if ( lastProp ) { for ( styleName in lastProp ) { if ( lastProp . hasOwnProperty ( styleName ) && ( ! nextProp || ! nextProp . hasOwnProperty ( styleName ) ) ) { styleUpdates = styleUpdates || { } ; styleUpdates [ styleName ] = '' ; } } for ( styleName in nextProp ) { if ( nextProp . hasOwnProperty ( styleName ) && lastProp [ styleName ] !== nextProp [ styleName ] ) { styleUpdates = styleUpdates || { } ; styleUpdates [ styleName ] = nextProp [ styleName ] ; } } } else { styleUpdates = nextProp ; } } else if ( registrationNameModules . hasOwnProperty ( propKey ) ) { if ( nextProp ) { enqueuePutListener ( this , propKey , nextProp , transaction ) ; } else if ( lastProp ) { deleteListener ( this , propKey ) ; } } else if ( isCustomComponent ( this . _tag , nextProps ) ) { if ( ! RESERVED_PROPS . hasOwnProperty ( propKey ) ) { DOMPropertyOperations . setValueForAttribute ( getNode ( this ) , propKey , nextProp ) ; } } else if ( DOMProperty . properties [ propKey ] || DOMProperty . isCustomAttribute ( propKey ) ) { var node = getNode ( this ) ; if ( nextProp != null ) { DOMPropertyOperations . setValueForProperty ( node , propKey , nextProp ) ; } else { DOMPropertyOperations . deleteValueForProperty ( node , propKey ) ; } } } if ( styleUpdates ) { CSSPropertyOperations . setValueForStyles ( getNode ( this ) , styleUpdates , this ) ; } }
Reconciles the properties by detecting differences in property values and
 updating the DOM as necessary.
Reconciles the properties by detecting differences in property values and updating the DOM as necessary .
// Only call deleteListener if there was a listener previously or // else willDeleteListener gets called when there wasn't actually a // listener (e.g., onClick={null}) // Unset styles on `lastProp` but not on `nextProp`. // Update styles that changed since `lastProp`. // Relies on `updateStylesByID` not mutating `styleUpdates`. // If we're updating to null or undefined, we should remove the property // from the DOM node instead of inadvertently setting to a string. This // brings us in line with the same behavior we have on initial render.