Skip to content

Commit

Permalink
Merge pull request #1399 from alibaba/fix-componentDidMount
Browse files Browse the repository at this point in the history
fix: componentDidMount exec not correct
  • Loading branch information
yuanyan authored Sep 29, 2019
2 parents 60c10d2 + 96fc7e5 commit d2ea864
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
48 changes: 46 additions & 2 deletions packages/rax/src/vdom/__tests__/composite.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,13 @@ describe('CompositeComponent', function() {
expect(logs).toEqual([
'componentWillMount1',
'render1',
'componentDidMount1',
'componentWillMount2',
'render2',
'componentDidMount2',
'componentWillMount3',
'render3',
'componentDidMount3',
'componentDidMount2',
'componentDidMount1',
'componentDidMountErrorBoundary',
'componentWillUnmount1',
'componentWillUnmount2',
Expand Down Expand Up @@ -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 <div />;
}
}
class App extends Component {
render() {
return <Child />;
}
}

const instance = render(<App />, 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 <div />;
}
}
class App extends Component {
render() {
return [
<Child key="1" />
];
}
}

const instance = render(<App />, container);
jest.runAllTimers();
expect(container.childNodes[0].tagName).toBe('DIV');
});

it('schedules sync updates when inside componentDidMount/Update', () => {
let container = createNodeElement('div');
let instance;
Expand Down
24 changes: 14 additions & 10 deletions packages/rax/src/vdom/composite.js
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand Down Expand Up @@ -156,7 +156,8 @@ class CompositeComponent extends BaseComponent {
this._parent,
instance,
this.__processChildContext(context),
nativeNodeMounter
nativeNodeMounter,
didMountWorks
);

if (error) {
Expand All @@ -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
Expand Down
12 changes: 9 additions & 3 deletions packages/rax/src/vdom/fragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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);
Expand All @@ -35,15 +41,15 @@ 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) => {
nativeNode = toArray(nativeNode);
for (let i = 0; i < nativeNode.length; i++) {
fragment.push(nativeNode[i]);
}
});
}, didMountWorks);
}

unmountComponent(shouldNotRemoveChild) {
Expand Down
16 changes: 11 additions & 5 deletions packages/rax/src/vdom/native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 = [];
Expand All @@ -84,7 +89,8 @@ export default class NativeComponent extends BaseComponent {
parent,
this[INSTANCE],
context,
nativeNodeMounter
nativeNodeMounter,
didMountWorks
);
renderedChildrenImage.push(mountImage);
}
Expand Down

0 comments on commit d2ea864

Please sign in to comment.