diff --git a/packages/rax/src/vdom/__tests__/composite.js b/packages/rax/src/vdom/__tests__/composite.js
index 90bd8827c5..bf212c8f96 100644
--- a/packages/rax/src/vdom/__tests__/composite.js
+++ b/packages/rax/src/vdom/__tests__/composite.js
@@ -494,13 +494,13 @@ describe('CompositeComponent', function() {
expect(logs).toEqual([
'componentWillMount1',
'render1',
- 'componentDidMount1',
'componentWillMount2',
'render2',
- 'componentDidMount2',
'componentWillMount3',
'render3',
'componentDidMount3',
+ 'componentDidMount2',
+ 'componentDidMount1',
'componentDidMountErrorBoundary',
'componentWillUnmount1',
'componentWillUnmount2',
@@ -533,6 +533,50 @@ describe('CompositeComponent', function() {
expect(container.childNodes[0].tagName).toBe('DIV');
});
+ it('render component that componentDidMount could get mounted DOM', () => {
+ let container = createNodeElement('div');
+ class Child extends Component {
+ componentDidMount() {
+ expect(container.childNodes[0].tagName).toBe('DIV');
+ }
+ render() {
+ return
;
+ }
+ }
+ class App extends Component {
+ render() {
+ return ;
+ }
+ }
+
+ const instance = render(, container);
+ jest.runAllTimers();
+ expect(container.childNodes[0].tagName).toBe('DIV');
+ });
+
+ it('render with fragment that componentDidMount could get mounted DOM', () => {
+ let container = createNodeElement('div');
+ class Child extends Component {
+ componentDidMount() {
+ expect(container.childNodes[0].tagName).toBe('DIV');
+ }
+ render() {
+ return ;
+ }
+ }
+ class App extends Component {
+ render() {
+ return [
+
+ ];
+ }
+ }
+
+ const instance = render(, container);
+ jest.runAllTimers();
+ expect(container.childNodes[0].tagName).toBe('DIV');
+ });
+
it('schedules sync updates when inside componentDidMount/Update', () => {
let container = createNodeElement('div');
let instance;
diff --git a/packages/rax/src/vdom/composite.js b/packages/rax/src/vdom/composite.js
index 5e5a4e1ecb..b763e50395 100644
--- a/packages/rax/src/vdom/composite.js
+++ b/packages/rax/src/vdom/composite.js
@@ -59,7 +59,7 @@ if (process.env.NODE_ENV !== 'production') {
* Composite Component
*/
class CompositeComponent extends BaseComponent {
- __mountComponent(parent, parentInstance, context, nativeNodeMounter) {
+ __mountComponent(parent, parentInstance, context, nativeNodeMounter, didMountWorks) {
this.__initComponent(parent, parentInstance, context);
if (process.env.NODE_ENV !== 'production') {
@@ -156,7 +156,8 @@ class CompositeComponent extends BaseComponent {
this._parent,
instance,
this.__processChildContext(context),
- nativeNodeMounter
+ nativeNodeMounter,
+ didMountWorks
);
if (error) {
@@ -168,15 +169,18 @@ class CompositeComponent extends BaseComponent {
}
if (instance.componentDidMount) {
- performInSandbox(() => {
- if (process.env.NODE_ENV !== 'production') {
- measureLifeCycle(() => {
+ const didMount = () => {
+ performInSandbox(() => {
+ if (process.env.NODE_ENV !== 'production') {
+ measureLifeCycle(() => {
+ instance.componentDidMount();
+ }, this._mountID, 'componentDidMount');
+ } else {
instance.componentDidMount();
- }, this._mountID, 'componentDidMount');
- } else {
- instance.componentDidMount();
- }
- }, instance);
+ }
+ }, instance);
+ };
+ didMountWorks ? didMountWorks.push(didMount) : didMount();
}
// Trigger setState callback in componentWillMount or boundary callback after rendered
diff --git a/packages/rax/src/vdom/fragment.js b/packages/rax/src/vdom/fragment.js
index a244444dc2..79f2855d73 100644
--- a/packages/rax/src/vdom/fragment.js
+++ b/packages/rax/src/vdom/fragment.js
@@ -15,7 +15,8 @@ class FragmentComponent extends NativeComponent {
instance[INTERNAL] = this;
// Mount children
- this.__mountChildren(this.__currentElement, context);
+ const didMountWorks = [];
+ this.__mountChildren(this.__currentElement, context, didMountWorks);
let fragment = this.__getNativeNode();
@@ -27,6 +28,11 @@ class FragmentComponent extends NativeComponent {
}
}
+ let work;
+ while (work = didMountWorks.pop()) {
+ work();
+ }
+
if (process.env.NODE_ENV !== 'production') {
this.__currentElement.type = FragmentComponent;
Host.reconciler.mountComponent(this);
@@ -35,7 +41,7 @@ class FragmentComponent extends NativeComponent {
return instance;
}
- __mountChildren(children, context) {
+ __mountChildren(children, context, didMountWorks) {
let fragment = this.__getNativeNode();
return this.__mountChildrenImpl(this._parent, children, context, (nativeNode) => {
@@ -43,7 +49,7 @@ class FragmentComponent extends NativeComponent {
for (let i = 0; i < nativeNode.length; i++) {
fragment.push(nativeNode[i]);
}
- });
+ }, didMountWorks);
}
unmountComponent(shouldNotRemoveChild) {
diff --git a/packages/rax/src/vdom/native.js b/packages/rax/src/vdom/native.js
index 2467552869..acddaf71cc 100644
--- a/packages/rax/src/vdom/native.js
+++ b/packages/rax/src/vdom/native.js
@@ -42,8 +42,13 @@ export default class NativeComponent extends BaseComponent {
if (appendType === TREE) {
// Should after process children when mount by tree mode
- this.__mountChildren(children, context);
+ const didMountWorks = [];
+ this.__mountChildren(children, context, didMountWorks);
this.__mountNativeNode(nativeNodeMounter);
+ let work;
+ while (work = didMountWorks.pop()) {
+ work();
+ }
} else {
// Should before process children when mount by node mode
this.__mountNativeNode(nativeNodeMounter);
@@ -62,14 +67,14 @@ export default class NativeComponent extends BaseComponent {
return instance;
}
- __mountChildren(children, context) {
+ __mountChildren(children, context, didMountWorks) {
if (children == null) return children;
const nativeNode = this.__getNativeNode();
- return this.__mountChildrenImpl(nativeNode, toArray(children), context);
+ return this.__mountChildrenImpl(nativeNode, toArray(children), context, null, didMountWorks);
}
- __mountChildrenImpl(parent, children, context, nativeNodeMounter) {
+ __mountChildrenImpl(parent, children, context, nativeNodeMounter, didMountWorks) {
let renderedChildren = this.__renderedChildren = {};
const renderedChildrenImage = [];
@@ -84,7 +89,8 @@ export default class NativeComponent extends BaseComponent {
parent,
this[INSTANCE],
context,
- nativeNodeMounter
+ nativeNodeMounter,
+ didMountWorks
);
renderedChildrenImage.push(mountImage);
}