mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #2894 from yungsters/local-event-trap-mixin
Fix LocalEventTrapMixin for Bad Tree State
This commit is contained in:
@@ -24,10 +24,17 @@ function remove(event) {
|
|||||||
var LocalEventTrapMixin = {
|
var LocalEventTrapMixin = {
|
||||||
trapBubbledEvent(topLevelType, handlerBaseName) {
|
trapBubbledEvent(topLevelType, handlerBaseName) {
|
||||||
invariant(this.isMounted(), 'Must be mounted to trap events');
|
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(
|
var listener = ReactBrowserEventEmitter.trapBubbledEvent(
|
||||||
topLevelType,
|
topLevelType,
|
||||||
handlerBaseName,
|
handlerBaseName,
|
||||||
this.getDOMNode()
|
node
|
||||||
);
|
);
|
||||||
this._localEventListeners =
|
this._localEventListeners =
|
||||||
accumulateInto(this._localEventListeners, listener);
|
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.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user