Callbacks passed to this setImmediate function are called at the end of the current update cycle, which is guaranteed to be asynchronous but in the same event loop (with the default batching strategy).
This is useful for new-style refs (#1373, #1554) and for fixing #1698.
Test Plan: jest
Breaking changes
- key/ref are no longer accessible on props but they are accessible on the
descriptors. This means that parents/owners can access it but not the
component itself.
- Descriptor factories are now plain functions and you can't rely on the
prototype or constructors of descriptors to identify the component type.
Existing descriptor factories are now wrapped in a legacy factory. Currently it
does nothing but it will give us a hook to track callers to factories that are
not using JSX but just invoking the function directly. It also proxies static
methods/properties to the underlying class. The newer factories don't have this
feature.
ReactTextComponent has it's own little factory because it's props is not an
object. This is a detail and will go away once ReactTextComponent no longer
needs descriptors.
If we don't error here, we end up with a confusing error later on in this.getDOMNode() where ReactMount doesn't have the proper container registered in its object.
See modification to the test-file: Basically we add a small hint at the end
of the error warning for propType errors to help identify which instantiation
of the component at hand is faulty.
We now forbid calling setState or forceUpdate if any component's render function is higher in the stack, not just the component you're trying to update. (We do this already now for React.renderComponent and React.unmountComponentAtNode.)
This also has the advantage that we can now remove CompositeLifeCycle.RECEIVING_STATE, making _compositeLifeCycleState easier to reason about (not to mention that RECEIVING_STATE was a confusing name) and making it possible to remove a try/finally from the render path which might help with perf.
Error should be thrown in the previous condition is "not" meet. And the href propType is described as optional in the comment, but the null check was missing.
This copies the propType and contextType validation to a wrapper around the
descriptor factory. By doing the validation early, we make it easier to track
down bugs. It also prepares for static type checking which should be done at the
usage site.
This validation is not yet active and is just logged using monitorCodeUse. This
will allow us to clean up callsites which would fail this new type of
validation.
I chose to copy the validation of abstracting it out since this is just an
intermediate step to avoid spamming consoles. This makes more a much cleaner
diff review/history. The original validation in the instance will be deleted as
soon as we can turn on the warnings.
Additionally, getDefaultProps are moved to become a static function which is
only executed once. It should be moved to statics but we don't have a
convenient way to merge mixins in statics right now. Deferring to ES6 classes.
This is still a breaking change since you can return an object or array from
getDefaultProps, which later gets mutated and now the shared instance is
mutated. Mutating an object that is passed into you from props is highly
discouraged and likely to lead to subtle bugs anyway. So I'm not too worried.
The defaultProps will later be resolved in the descriptor factory. This will
enable a perf optimizations where we don't create an unnecessary object
allocation when you use default props. It also means that ReactChildren.map
has access to resolved properties which gives them consistent behavior whether
or not the default prop is specified.
binds static methods on the descriptor to the component's actual constructor, so that `foo.constructor.bar()` and `Foo.bar()` run with the same `this`.
I ran into a really difficult-to-debug issue with a React app with SVG
elements. Christopher sat down with me for a while and we finally figured out
that the browser was moving non-SVG elements out of a parent `<svg>` node which
triggered the `processUpdates()` invariant. This updates the error message
thrown from there to include this scenario in the possible issues list.
For boolean-like objects, I've added hasOwnProperty checks in addition to the existing truthiness check even though for most of these dicts, we leave out false keys instead of setting them explicitly to false.
In DOMPropertyOperations, we don't need to check hasOwnProperty if the property is in isStandardName because (with the exception of getPossibleStandardName) the dicts on DOMProperty will now be consistently populated with every valid attribute.
With this, multiple setState calls triggered by a componentDidUpdate handler (or similar) will be batched together, regardless of if the original setState call was in a batching context.
I also cleaned up some inconsistencies with the order of component updates and callbacks in situations where one component's update directly causes another to update.
Fixes#1147. Helps with #1353 and #1245 as well, though doesn't completely fix them yet.
Test Plan:
grunt test
This copies the propType and contextType validation to a wrapper around the
descriptor factory. By doing the validation early, we make it easier to track
down bugs. It also prepares for static type checking which should be done at the
usage site.
This validation is not yet active and is just logged using monitorCodeUse. This
will allow us to clean up callsites which would fail this new type of
validation.
I chose to copy the validation instead of abstracting it out to a common abstraction. This is just an
intermediate step to avoid spamming consoles. The original validation in the instance will be deleted as soon as we can turn on the warnings at the callsite. Copy+Delete makes this a more a much cleaner diff review/history.
Additionally, getDefaultProps are moved to become a static function which is
only executed once. It should be moved to statics but we don't have a
convenient way to merge mixins in statics right now. Deferring to ES6 classes.
This is still a breaking change since you can return an object or array from
getDefaultProps, which later gets mutated and now the shared instance is
mutated. Mutating an object that is passed into you from props is highly
discouraged and likely to lead to subtle bugs anyway. So I'm not too worried.
The defaultProps are now resolved in the descriptor factory. This will enable
a perf optimizations where we don't create an unnecessary object allocation
when you use default props. It also means that ReactChildren.map has access to
resolved properties which gives them consistent behavior whether or not the
default prop is specified.
This is a breaking change since it can affect how mapping over children and
transferPropsTo works together with defaultProps.
Previous behavior: `transferPropsTo(<div style={{color: 'red'}} />)` would get `color` overriden if we transfer in a `style={{color: 'blue'}}`. This is inconsistent with how other props are transfered.
This simply reverses the order of arguments.
closes#1435