From 61e8ee71b65b04f428ac0ca9629ff3dc90d294f5 Mon Sep 17 00:00:00 2001 From: Michael Ridgway Date: Mon, 12 Jun 2017 12:21:27 -0700 Subject: [PATCH] [#9627] Fix create-react-class isMounted ordering issue (#9638) * [#9627] Fix create-react-class isMounted ordering issue Split the IsMountedMixin in two so that the __isMounted flag is set to false after componentWillUnmount is executed in mixins and the component. * Revert changes to integration test --- addons/create-react-class/factory.js | 10 +++++++--- addons/create-react-class/test.js | 26 +++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/addons/create-react-class/factory.js b/addons/create-react-class/factory.js index 5e2e0561fa..61741cce4b 100644 --- a/addons/create-react-class/factory.js +++ b/addons/create-react-class/factory.js @@ -584,10 +584,13 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) { } } - var IsMountedMixin = { + var IsMountedPreMixin = { componentDidMount: function () { this.__isMounted = true; - }, + } + }; + + var IsMountedPostMixin = { componentWillUnmount: function () { this.__isMounted = false; } @@ -679,8 +682,9 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) { injectedMixins.forEach(mixSpecIntoComponent.bind(null, Constructor)); - mixSpecIntoComponent(Constructor, IsMountedMixin); + mixSpecIntoComponent(Constructor, IsMountedPreMixin); mixSpecIntoComponent(Constructor, spec); + mixSpecIntoComponent(Constructor, IsMountedPostMixin); // Initialize the defaultProps property after all mixins have been merged. if (Constructor.getDefaultProps) { diff --git a/addons/create-react-class/test.js b/addons/create-react-class/test.js index 01da8790f7..a2daebe762 100644 --- a/addons/create-react-class/test.js +++ b/addons/create-react-class/test.js @@ -394,6 +394,25 @@ describe('ReactClass-spec', () => { var instance; var Component = createReactClass({ displayName: 'MyComponent', + mixins: [ + { + componentWillMount() { + this.log('mixin.componentWillMount'); + }, + componentDidMount() { + this.log('mixin.componentDidMount'); + }, + componentWillUpdate() { + this.log('mixin.componentWillUpdate'); + }, + componentDidUpdate() { + this.log('mixin.componentDidUpdate'); + }, + componentWillUnmount() { + this.log('mixin.componentWillUnmount'); + }, + }, + ], log(name) { ops.push(`${name}: ${this.isMounted()}`); }, @@ -430,13 +449,18 @@ describe('ReactClass-spec', () => { instance.log('after unmount'); expect(ops).toEqual([ 'getInitialState: false', + 'mixin.componentWillMount: false', 'componentWillMount: false', 'render: false', + 'mixin.componentDidMount: true', 'componentDidMount: true', + 'mixin.componentWillUpdate: true', 'componentWillUpdate: true', 'render: true', + 'mixin.componentDidUpdate: true', 'componentDidUpdate: true', - 'componentWillUnmount: false', + 'mixin.componentWillUnmount: true', + 'componentWillUnmount: true', 'after unmount: false', ]);