Skip to content

Commit

Permalink
Fix null node issue in ReactCSSTransitionGroup (facebook#6958)
Browse files Browse the repository at this point in the history
(cherry picked from commit c9eb572)
  • Loading branch information
keyz authored and zpao committed Jun 8, 2016
1 parent 3ce1a61 commit 41207fa
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
25 changes: 15 additions & 10 deletions src/addons/transitions/ReactCSSTransitionGroupChild.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ var ReactCSSTransitionGroupChild = React.createClass({
CSSCore.addClass(node, className);

// Need to do this to actually trigger a transition.
this.queueClass(activeClassName);
this.queueClassAndNode(activeClassName, node);

// If the user specified a timeout delay.
if (userSpecifiedDelay) {
Expand All @@ -102,26 +102,29 @@ var ReactCSSTransitionGroupChild = React.createClass({
}
},

queueClass: function(className) {
this.classNameQueue.push(className);
queueClassAndNode: function(className, node) {
this.classNameAndNodeQueue.push({
className: className,
node: node,
});

if (!this.timeout) {
this.timeout = setTimeout(this.flushClassNameQueue, TICK);
this.timeout = setTimeout(this.flushClassNameAndNodeQueue, TICK);
}
},

flushClassNameQueue: function() {
flushClassNameAndNodeQueue: function() {
if (this.isMounted()) {
this.classNameQueue.forEach(
CSSCore.addClass.bind(CSSCore, ReactDOM.findDOMNode(this))
);
this.classNameAndNodeQueue.forEach(function(obj) {
CSSCore.addClass(obj.node, obj.className);
});
}
this.classNameQueue.length = 0;
this.classNameAndNodeQueue.length = 0;
this.timeout = null;
},

componentWillMount: function() {
this.classNameQueue = [];
this.classNameAndNodeQueue = [];
this.transitionTimeouts = [];
},

Expand All @@ -132,6 +135,8 @@ var ReactCSSTransitionGroupChild = React.createClass({
this.transitionTimeouts.forEach(function(timeout) {
clearTimeout(timeout);
});

this.classNameAndNodeQueue.length = 0;
},

componentWillAppear: function(done) {
Expand Down
38 changes: 38 additions & 0 deletions src/addons/transitions/__tests__/ReactCSSTransitionGroup-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,42 @@ describe('ReactCSSTransitionGroup', function() {
// Testing that no exception is thrown here, as the timeout has been cleared.
jest.runAllTimers();
});

it('should handle unmounted elements properly', function() {
var Child = React.createClass({
render() {
if (!this.props.show) {
return null;
}
return <div />;
},
});

var Component = React.createClass({
getInitialState() {
return { showChild: true };
},

componentDidMount() {
this.setState({ showChild: false });
},

render() {
return (
<ReactCSSTransitionGroup
transitionName="yolo"
transitionAppear={true}
transitionAppearTimeout={0}
>
<Child show={this.state.showChild} />
</ReactCSSTransitionGroup>
);
},
});

ReactDOM.render(<Component/>, container);

// Testing that no exception is thrown here, as the timeout has been cleared.
jest.runAllTimers();
});
});

0 comments on commit 41207fa

Please sign in to comment.