Summary:
Changes the way we instrument methods for `ReactPerf` so that developer tools can assign implicit method names to measured functions.
Reviewers: @zpao @sebmarkbage
Update to the animation documentation for ReactTransitionGroup to clear the air on where one can use it.
If someone tries to use it off of React.addons.ReactTransitionGroup, which is undefined, instead of its real location, React.addons.TransitionGroup, they get a vague error about being unable to set defaultProps of undefined in the React createElement body.
Summary:
Currently, `ReactClass` mutates values returned by `getDefaultProps`, `getInitialState`, and `getChildContext`. This is bad because the objects may, for example, be cached and re-used across instances of a React component.
This changes `ReactClass` to instead create a new object. In return for allocating a new object, I've replaced `mapObject` with a `for ... in` so that we are no longer allocating an unused object.
Fair trade, IMO.
Test Plan:
Ran unit tests successfully:
```
npm run jest
```
Conflicts:
src/core/ReactCompositeComponent.js
Conflicts:
src/class/ReactClass.js
The word "Friends" does establish a relationship however it does not fit in the vernacular of react.
This change makes the phrase more explicit and more familiar.
We currently have three DOM specific hooks that get injected. I move those
out to ReactComponentEnvironment. The idea is to eventually remove this
injection as the reconciler gets refactored.
There is also a BackendIDOperation which is specific to the DOM component
itself so I move this injection to be more specific to the DOMComponent.
E.g. it makes sense for it to be injectable for cross-worker DOM operations
but it doesn't make sense for ART components.
If several children complete leaving before rendering TransitionGroup,
only the last one was removed. This could easily happen if
callback in componentWillLeave is called synchronously and several items
are removed from array. The other case is when ReactCSSTransitionGroup
has transitionLeave={false} and array is also cleaned up.
The bug was happening because this.state.children was used as a base for
children removal and it wasn't updated until the render, so only the last
removal was actually happening.
Fix involves keeping the updated children state between invocations of
_handleDoneLeaving. After updating this.state and rendering,
updatedState is cleaned up and ready for subsequent array modifications.
Test case included.
This is part of moving more logic out of the base classes.
setProps, replaceProps etc. are not accessible from anything other than
ReactClass so we can safely move it to ReactCompositeComponent.
mountComponentIntoNode is tightly coupled to ReactMount. It's part of the
outer abstraction, the mount point, not the individual component.
The _owner field is unnecessary since it's reachable from _currentElement.
The _lifeCycle field is unnecessary because an internal component should
not even need to exist at all if it's unmounted. It should be dereferenced
internally, and never exposed externally.
The only case where it's important is for batching updates where we
currently avoid calling performUpdateIfNecessary if it's mounted. However,
this function is already only executed "if necessary" so we just make sure
that it's not necessary after unmount by resetting all the pending fields.
We currently make a copy of .style because we support mutating the style object in place. Instead of storing it back on props, store it separately on the component instance so that we don't mutate props anywhere. This is gross but should all be cleaned up after #2008 is resolved.
Test Plan: jest
createFullPageComponent doesn't reference ReactBrowserComponentMixin directly so the mixin should get injected before the components are created. Previously, this test failed because getDOMNode wasn't present on the component instance.
Test Plan: jest
...unless they already have a wrapper. Also, add tagName to every wrapper.
This ensures that refs are consistent. They always look like composite
components. This effectively hides the internal implementation details of
real DOM components since you can no longer get a ref to one.
In the future we might want to drop this wrapper and have refs refer
directly to the DOM node.
I currently use a hacky way of auto-wrapping inside of ReactNativeComponent
so that any given string can be wrapped. Better suggestions are welcome.
Fixes#2493, also closes#2353 as it incorporates a variant of that fix.
- Instead of having getEmptyComponent return `<noscript />` directly, wrap it in a class that we can easily identify later as being an empty component
- Cache the empty component element instead of recreating one each time
- Avoid touching the nullComponentIdsRegistry dictionary at all when not dealing with empty components
- Move empty-component tests to a separate file
Test Plan: jest
ReactTextComponent's implementation is DOM-specific; instead of flattenChildren creating the ReactTextComponent instances, ReactNativeComponent now takes care of having ReactTextComponent injected and creating the component instance. I also renamed ReactTextComponent to ReactDOMTextComponent and moved it to browser/ui/ where it belongs. ReactDOMTextComponent no longer inherits directly from ReactComponent and instead implements construct and {mount,receive,unmount}Component directly.
This diff removes `ReactTestUtils.isTextComponent` which should have previously never returned true when using public APIs.
Test Plan: jest, use ballmer-peak example.
"appear" differs from "enter" in that all children of a transition group at mount time will "appear" but will not "enter". All children later added to an existing transition group will "enter" but not "appear".
This extra transition phase allows for animation-on-mount effects.
A mirroring "appear" prop has been added to ReactCSSTransitionGroup, however for reverse-compatibility (and because "appear" is less common) it defaults to false.
Thanks to @afa for his work investigating the possible ways to implement this.
monitorScrollValue is only called with `ViewportMetrics.refreshScrollValues` (https://github.com/facebook/react/blob/master/src/browser/ReactBrowserEventEmitter.js#L333-L334) and the window scroll properties (scrollTop and scrollLeft) don't change on resize (from my testings), so there is no need to listen for window resizes.
I also tried to see why the resize listener was added from the history but it was introduced on the initial commits.
I created a simple page that shows that http://jsbin.com/nuhice, open the console.