From 96fc7e5f5a52dfc65690afd1803990a49b2980d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=83=E5=BD=A6?= Date: Fri, 27 Sep 2019 21:36:36 +0800 Subject: [PATCH] fix: didMount works correct in fragment --- packages/rax/src/vdom/__tests__/composite.js | 48 +++++++++++++++++++- packages/rax/src/vdom/fragment.js | 12 +++-- 2 files changed, 55 insertions(+), 5 deletions(-) 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/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) {