Merge pull request #2894 from yungsters/local-event-trap-mixin

Fix LocalEventTrapMixin for Bad Tree State
This commit is contained in:
Timothy Yung
2015-01-21 15:34:32 -08:00
2 changed files with 54 additions and 1 deletions
@@ -24,10 +24,17 @@ function remove(event) {
var LocalEventTrapMixin = {
trapBubbledEvent(topLevelType, handlerBaseName) {
invariant(this.isMounted(), 'Must be mounted to trap events');
// If a component renders to null or if another component fatals and causes
// the state of the tree to be corrupted, `node` here can be null.
var node = this.getDOMNode();
invariant(
node,
'LocalEventTrapMixin.trapBubbledEvent(...): Requires node to be rendered.'
);
var listener = ReactBrowserEventEmitter.trapBubbledEvent(
topLevelType,
handlerBaseName,
this.getDOMNode()
node
);
this._localEventListeners =
accumulateInto(this._localEventListeners, listener);
@@ -0,0 +1,46 @@
/**
* Copyright 2013-2014, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails react-core
*/
'use strict';
describe('LocalEventTrapMixin', function() {
var EventConstants;
var LocalEventTrapMixin;
var React;
var ReactTestUtils;
beforeEach(function() {
EventConstants = require('EventConstants');
LocalEventTrapMixin = require('LocalEventTrapMixin');
React = require('React');
ReactTestUtils = require('ReactTestUtils');
});
it('does not fatal when trapping bubbled state on null', function() {
var BadImage = React.createClass({
mixins: [LocalEventTrapMixin],
render: function() {
return null;
},
componentDidMount: function() {
this.trapBubbledEvent(EventConstants.topLevelTypes.topLoad, 'load');
}
});
expect(function() {
ReactTestUtils.renderIntoDocument(<BadImage />);
}).toThrow(
'Invariant Violation: ' +
'LocalEventTrapMixin.trapBubbledEvent(...): ' +
'Requires node to be rendered.'
);
});
});