mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Revert useEvent PRs (#18438)
* Revert "ReactDOM.useEvent: enable on internal www and add inspection test (#18395)" This reverts commite0ab1a429d. * Revert "ReactDOM.useEvent: Add support for experimental scopes API (#18375)" This reverts commita16b349745. * ReactDOM.useEvent: Add support for experimental scopes API
This commit is contained in:
+1
-5
@@ -15,7 +15,6 @@ import type {
|
||||
ReactProviderType,
|
||||
ReactEventResponder,
|
||||
ReactEventResponderListener,
|
||||
ReactScopeMethods,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
||||
import type {Hook, TimeoutConfig} from 'react-reconciler/src/ReactFiberHooks';
|
||||
@@ -45,10 +44,7 @@ type HookLogEntry = {
|
||||
|
||||
type ReactDebugListenerMap = {|
|
||||
clear: () => void,
|
||||
setListener: (
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
callback: ?(Event) => void,
|
||||
) => void,
|
||||
setListener: (target: EventTarget, callback: ?(Event) => void) => void,
|
||||
|};
|
||||
|
||||
let hookLog: Array<HookLogEntry> = [];
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactDebugTools;
|
||||
|
||||
describe('ReactHooksInspection', () => {
|
||||
@@ -19,9 +18,7 @@ describe('ReactHooksInspection', () => {
|
||||
jest.resetModules();
|
||||
const ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
ReactFeatureFlags.enableDeprecatedFlareAPI = true;
|
||||
ReactFeatureFlags.enableUseEventAPI = true;
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
ReactDebugTools = require('react-debug-tools');
|
||||
});
|
||||
|
||||
@@ -50,44 +47,4 @@ describe('ReactHooksInspection', () => {
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should inspect a simple ReactDOM.useEvent hook', () => {
|
||||
let clickHandle;
|
||||
let ref;
|
||||
|
||||
const effect = () => {
|
||||
clickHandle.setListener(ref.current, () => {});
|
||||
};
|
||||
|
||||
function Foo(props) {
|
||||
ref = React.useRef(null);
|
||||
clickHandle = ReactDOM.unstable_useEvent('click');
|
||||
React.useEffect(effect);
|
||||
return <div ref={ref}>Hello world</div>;
|
||||
}
|
||||
let tree = ReactDebugTools.inspectHooks(Foo, {});
|
||||
expect(tree).toEqual([
|
||||
{
|
||||
isStateEditable: false,
|
||||
id: 0,
|
||||
name: 'Ref',
|
||||
subHooks: [],
|
||||
value: null,
|
||||
},
|
||||
{
|
||||
isStateEditable: false,
|
||||
id: 1,
|
||||
name: 'Event',
|
||||
value: {capture: false, passive: undefined, priority: 0, type: 'click'},
|
||||
subHooks: [],
|
||||
},
|
||||
{
|
||||
isStateEditable: false,
|
||||
id: 2,
|
||||
name: 'Effect',
|
||||
value: effect,
|
||||
subHooks: [],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1348,10 +1348,6 @@ export function listenToEventResponderEventTypes(
|
||||
const targetEventType = isPassive
|
||||
? eventType
|
||||
: eventType.substring(0, eventType.length - 7);
|
||||
// We don't listen to this as we actually emulate it in the host config
|
||||
if (targetEventType === 'beforeblur') {
|
||||
continue;
|
||||
}
|
||||
if (!listenerMap.has(eventKey)) {
|
||||
if (isPassive) {
|
||||
const activeKey = targetEventType + '_active';
|
||||
|
||||
+13
-24
@@ -9,15 +9,6 @@
|
||||
|
||||
import type {TopLevelType} from 'legacy-events/TopLevelEventTypes';
|
||||
import type {RootType} from './ReactDOMRoot';
|
||||
import type {
|
||||
ReactDOMEventResponder,
|
||||
ReactDOMEventResponderInstance,
|
||||
ReactDOMFundamentalComponentInstance,
|
||||
ReactDOMListener,
|
||||
ReactDOMListenerEvent,
|
||||
ReactDOMListenerMap,
|
||||
} from '../shared/ReactDOMTypes';
|
||||
import type {ReactScopeMethods} from 'shared/ReactTypes';
|
||||
|
||||
import {
|
||||
precacheFiberNode,
|
||||
@@ -58,6 +49,14 @@ import {
|
||||
} from '../shared/HTMLNodeType';
|
||||
import dangerousStyleValue from '../shared/dangerousStyleValue';
|
||||
|
||||
import type {
|
||||
ReactDOMEventResponder,
|
||||
ReactDOMEventResponderInstance,
|
||||
ReactDOMFundamentalComponentInstance,
|
||||
ReactDOMListener,
|
||||
ReactDOMListenerEvent,
|
||||
ReactDOMListenerMap,
|
||||
} from '../shared/ReactDOMTypes';
|
||||
import {
|
||||
mountEventResponder,
|
||||
unmountEventResponder,
|
||||
@@ -70,7 +69,6 @@ import {
|
||||
enableDeprecatedFlareAPI,
|
||||
enableFundamentalAPI,
|
||||
enableUseEventAPI,
|
||||
enableScopeAPI,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {
|
||||
@@ -81,13 +79,10 @@ import {
|
||||
isManagedDOMElement,
|
||||
isValidEventTarget,
|
||||
listenToTopLevelEvent,
|
||||
attachListenerToManagedDOMElement,
|
||||
detachListenerFromManagedDOMElement,
|
||||
attachTargetEventListener,
|
||||
attachListenerFromManagedDOMElement,
|
||||
detachTargetEventListener,
|
||||
isReactScope,
|
||||
attachListenerToReactScope,
|
||||
detachListenerFromReactScope,
|
||||
attachTargetEventListener,
|
||||
} from '../events/DOMModernPluginEventSystem';
|
||||
import {getListenerMapForElement} from '../events/DOMEventListenerMap';
|
||||
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
|
||||
@@ -1165,9 +1160,7 @@ export function mountEventListener(listener: ReactDOMListener): void {
|
||||
if (enableUseEventAPI) {
|
||||
const {target} = listener;
|
||||
if (isManagedDOMElement(target)) {
|
||||
attachListenerToManagedDOMElement(listener);
|
||||
} else if (enableScopeAPI && isReactScope(target)) {
|
||||
attachListenerToReactScope(listener);
|
||||
attachListenerFromManagedDOMElement(listener);
|
||||
} else {
|
||||
attachTargetEventListener(listener);
|
||||
}
|
||||
@@ -1179,8 +1172,6 @@ export function unmountEventListener(listener: ReactDOMListener): void {
|
||||
const {target} = listener;
|
||||
if (isManagedDOMElement(target)) {
|
||||
detachListenerFromManagedDOMElement(listener);
|
||||
} else if (enableScopeAPI && isReactScope(target)) {
|
||||
detachListenerFromReactScope(listener);
|
||||
} else {
|
||||
detachTargetEventListener(listener);
|
||||
}
|
||||
@@ -1188,15 +1179,13 @@ export function unmountEventListener(listener: ReactDOMListener): void {
|
||||
}
|
||||
|
||||
export function validateEventListenerTarget(
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
target: EventTarget,
|
||||
listener: ?(Event) => void,
|
||||
): boolean {
|
||||
if (enableUseEventAPI) {
|
||||
if (
|
||||
target != null &&
|
||||
(isManagedDOMElement(target) ||
|
||||
isValidEventTarget(target) ||
|
||||
isReactScope(target))
|
||||
(isManagedDOMElement(target) || isValidEventTarget(target))
|
||||
) {
|
||||
if (listener == null || typeof listener === 'function') {
|
||||
return true;
|
||||
|
||||
+22
-93
@@ -14,7 +14,7 @@ import type {
|
||||
ElementListenerMapEntry,
|
||||
} from '../events/DOMEventListenerMap';
|
||||
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
|
||||
import type {EventPriority, ReactScopeMethods} from 'shared/ReactTypes';
|
||||
import type {EventPriority} from 'shared/ReactTypes';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
||||
import type {PluginModule} from 'legacy-events/PluginModuleType';
|
||||
import type {
|
||||
@@ -142,11 +142,8 @@ const emptyDispatchConfigForCustomEvents: CustomDispatchConfig = {
|
||||
|
||||
const isArray = Array.isArray;
|
||||
|
||||
// TODO: we should remove the FlowFixMes and the casting to figure out how to make
|
||||
// these patterns work properly.
|
||||
// $FlowFixMe: Flow struggles with this pattern, so we also have to cast it.
|
||||
const PossiblyWeakMap = ((typeof WeakMap === 'function' ? WeakMap : Map): any);
|
||||
|
||||
// $FlowFixMe: Flow struggles with this pattern
|
||||
const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
|
||||
// $FlowFixMe: Flow cannot handle polymorphic WeakMaps
|
||||
export const eventTargetEventListenerStore: WeakMap<
|
||||
EventTarget,
|
||||
@@ -156,15 +153,6 @@ export const eventTargetEventListenerStore: WeakMap<
|
||||
>,
|
||||
> = new PossiblyWeakMap();
|
||||
|
||||
// $FlowFixMe: Flow cannot handle polymorphic WeakMaps
|
||||
export const reactScopeListenerStore: WeakMap<
|
||||
ReactScopeMethods,
|
||||
Map<
|
||||
DOMTopLevelEventType,
|
||||
{bubbled: Set<ReactDOMListener>, captured: Set<ReactDOMListener>},
|
||||
>,
|
||||
> = new PossiblyWeakMap();
|
||||
|
||||
function dispatchEventsForPlugins(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
eventSystemFlags: EventSystemFlags,
|
||||
@@ -318,20 +306,12 @@ function isMatchingRootContainer(
|
||||
);
|
||||
}
|
||||
|
||||
export function isManagedDOMElement(
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
): boolean {
|
||||
export function isManagedDOMElement(target: EventTarget): boolean {
|
||||
return getClosestInstanceFromNode(((target: any): Node)) !== null;
|
||||
}
|
||||
|
||||
export function isValidEventTarget(
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
): boolean {
|
||||
return typeof (target: Object).addEventListener === 'function';
|
||||
}
|
||||
|
||||
export function isReactScope(target: EventTarget | ReactScopeMethods): boolean {
|
||||
return typeof (target: Object).getChildContextValues === 'function';
|
||||
export function isValidEventTarget(target: EventTarget): boolean {
|
||||
return typeof target.addEventListener === 'function';
|
||||
}
|
||||
|
||||
export function dispatchEventForPluginEventSystem(
|
||||
@@ -466,16 +446,18 @@ function addEventTypeToDispatchConfig(type: DOMTopLevelEventType): void {
|
||||
}
|
||||
}
|
||||
|
||||
export function attachListenerToManagedDOMElement(
|
||||
export function attachListenerFromManagedDOMElement(
|
||||
listener: ReactDOMListener,
|
||||
): void {
|
||||
const {event, target} = listener;
|
||||
const {passive, priority, type} = event;
|
||||
|
||||
const managedTargetElement = ((target: any): Element);
|
||||
const containerEventTarget = getNearestRootOrPortalContainer(
|
||||
managedTargetElement,
|
||||
);
|
||||
const possibleManagedTarget = ((target: any): Element);
|
||||
let containerEventTarget = target;
|
||||
if (getClosestInstanceFromNode(possibleManagedTarget)) {
|
||||
containerEventTarget = getNearestRootOrPortalContainer(
|
||||
possibleManagedTarget,
|
||||
);
|
||||
}
|
||||
const listenerMap = getListenerMapForElement(containerEventTarget);
|
||||
// Add the event listener to the target container (falling back to
|
||||
// the target if we didn't find one).
|
||||
@@ -487,11 +469,11 @@ export function attachListenerToManagedDOMElement(
|
||||
priority,
|
||||
);
|
||||
// Get the internal listeners Set from the target instance.
|
||||
let listeners = getListenersFromTarget(managedTargetElement);
|
||||
let listeners = getListenersFromTarget(target);
|
||||
// If we don't have any listeners, then we need to init them.
|
||||
if (listeners === null) {
|
||||
listeners = new Set();
|
||||
initListenersSet(managedTargetElement, listeners);
|
||||
initListenersSet(target, listeners);
|
||||
}
|
||||
// Add our listener to the listeners Set.
|
||||
listeners.add(listener);
|
||||
@@ -503,9 +485,8 @@ export function detachListenerFromManagedDOMElement(
|
||||
listener: ReactDOMListener,
|
||||
): void {
|
||||
const {target} = listener;
|
||||
const managedTargetElement = ((target: any): Element);
|
||||
// Get the internal listeners Set from the target instance.
|
||||
const listeners = getListenersFromTarget(managedTargetElement);
|
||||
const listeners = getListenersFromTarget(target);
|
||||
if (listeners !== null) {
|
||||
// Remove out listener from the listeners Set.
|
||||
listeners.delete(listener);
|
||||
@@ -515,21 +496,13 @@ export function detachListenerFromManagedDOMElement(
|
||||
export function attachTargetEventListener(listener: ReactDOMListener): void {
|
||||
const {event, target} = listener;
|
||||
const {capture, passive, priority, type} = event;
|
||||
const eventTarget = ((target: any): EventTarget);
|
||||
const listenerMap = getListenerMapForElement(eventTarget);
|
||||
const listenerMap = getListenerMapForElement(target);
|
||||
// Add the event listener to the TargetEvent object.
|
||||
listenToTopLevelEvent(
|
||||
type,
|
||||
eventTarget,
|
||||
listenerMap,
|
||||
passive,
|
||||
priority,
|
||||
capture,
|
||||
);
|
||||
let eventTypeMap = eventTargetEventListenerStore.get(eventTarget);
|
||||
listenToTopLevelEvent(type, target, listenerMap, passive, priority, capture);
|
||||
let eventTypeMap = eventTargetEventListenerStore.get(target);
|
||||
if (eventTypeMap === undefined) {
|
||||
eventTypeMap = new Map();
|
||||
eventTargetEventListenerStore.set(eventTarget, eventTypeMap);
|
||||
eventTargetEventListenerStore.set(target, eventTypeMap);
|
||||
}
|
||||
// Get the listeners by the event type
|
||||
let listeners = eventTypeMap.get(type);
|
||||
@@ -550,51 +523,7 @@ export function attachTargetEventListener(listener: ReactDOMListener): void {
|
||||
export function detachTargetEventListener(listener: ReactDOMListener): void {
|
||||
const {event, target} = listener;
|
||||
const {capture, type} = event;
|
||||
const validEventTarget = ((target: any): EventTarget);
|
||||
const eventTypeMap = eventTargetEventListenerStore.get(validEventTarget);
|
||||
if (eventTypeMap !== undefined) {
|
||||
const listeners = eventTypeMap.get(type);
|
||||
if (listeners !== undefined) {
|
||||
// Remove out listener from the listeners Set.
|
||||
if (capture) {
|
||||
listeners.captured.delete(listener);
|
||||
} else {
|
||||
listeners.bubbled.delete(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function attachListenerToReactScope(listener: ReactDOMListener): void {
|
||||
const {event, target} = listener;
|
||||
const {capture, type} = event;
|
||||
const reactScope = ((target: any): ReactScopeMethods);
|
||||
let eventTypeMap = reactScopeListenerStore.get(reactScope);
|
||||
if (eventTypeMap === undefined) {
|
||||
eventTypeMap = new Map();
|
||||
reactScopeListenerStore.set(reactScope, eventTypeMap);
|
||||
}
|
||||
// Get the listeners by the event type
|
||||
let listeners = eventTypeMap.get(type);
|
||||
if (listeners === undefined) {
|
||||
listeners = {captured: new Set(), bubbled: new Set()};
|
||||
eventTypeMap.set(type, listeners);
|
||||
}
|
||||
// Add our listener to the listeners Set.
|
||||
if (capture) {
|
||||
listeners.captured.add(listener);
|
||||
} else {
|
||||
listeners.bubbled.add(listener);
|
||||
}
|
||||
// Finally, add the event to our known event types list.
|
||||
addEventTypeToDispatchConfig(type);
|
||||
}
|
||||
|
||||
export function detachListenerFromReactScope(listener: ReactDOMListener): void {
|
||||
const {event, target} = listener;
|
||||
const {capture, type} = event;
|
||||
const reactScope = ((target: any): ReactScopeMethods);
|
||||
const eventTypeMap = reactScopeListenerStore.get(reactScope);
|
||||
const eventTypeMap = eventTargetEventListenerStore.get(target);
|
||||
if (eventTypeMap !== undefined) {
|
||||
const listeners = eventTypeMap.get(type);
|
||||
if (listeners !== undefined) {
|
||||
|
||||
@@ -2327,139 +2327,6 @@ describe('DOMModernPluginEventSystem', () => {
|
||||
document.body.removeChild(container2);
|
||||
},
|
||||
);
|
||||
|
||||
describe('Compatibility with Scopes API', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
ReactFeatureFlags.enableModernEventSystem = true;
|
||||
ReactFeatureFlags.enableUseEventAPI = true;
|
||||
ReactFeatureFlags.enableScopeAPI = true;
|
||||
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
Scheduler = require('scheduler');
|
||||
ReactDOMServer = require('react-dom/server');
|
||||
});
|
||||
|
||||
it('handle propagation of click events on a scope', () => {
|
||||
const buttonRef = React.createRef();
|
||||
const log = [];
|
||||
const onClick = jest.fn(e =>
|
||||
log.push(['bubble', e.currentTarget]),
|
||||
);
|
||||
const onClickCapture = jest.fn(e =>
|
||||
log.push(['capture', e.currentTarget]),
|
||||
);
|
||||
const TestScope = React.unstable_createScope();
|
||||
|
||||
function Test() {
|
||||
const click = ReactDOM.unstable_useEvent('click');
|
||||
const clickCapture = ReactDOM.unstable_useEvent('click', {
|
||||
capture: true,
|
||||
});
|
||||
const scopeRef = React.useRef(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
click.setListener(scopeRef.current, onClick);
|
||||
clickCapture.setListener(scopeRef.current, onClickCapture);
|
||||
});
|
||||
|
||||
return (
|
||||
<TestScope ref={scopeRef}>
|
||||
<button ref={buttonRef} />
|
||||
</TestScope>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<Test />, container);
|
||||
Scheduler.unstable_flushAll();
|
||||
|
||||
const buttonElement = buttonRef.current;
|
||||
dispatchClickEvent(buttonElement);
|
||||
|
||||
expect(onClick).toHaveBeenCalledTimes(1);
|
||||
expect(onClickCapture).toHaveBeenCalledTimes(1);
|
||||
expect(log).toEqual([
|
||||
['capture', buttonElement],
|
||||
['bubble', buttonElement],
|
||||
]);
|
||||
});
|
||||
|
||||
it('handle mixed propagation of click events on a scope', () => {
|
||||
const buttonRef = React.createRef();
|
||||
const divRef = React.createRef();
|
||||
const log = [];
|
||||
const onClick = jest.fn(e =>
|
||||
log.push(['bubble', e.currentTarget]),
|
||||
);
|
||||
const onClickCapture = jest.fn(e =>
|
||||
log.push(['capture', e.currentTarget]),
|
||||
);
|
||||
const TestScope = React.unstable_createScope();
|
||||
|
||||
function Test() {
|
||||
const click = ReactDOM.unstable_useEvent('click');
|
||||
const clickCapture = ReactDOM.unstable_useEvent('click', {
|
||||
capture: true,
|
||||
});
|
||||
const scopeRef = React.useRef(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
click.setListener(scopeRef.current, onClick);
|
||||
clickCapture.setListener(scopeRef.current, onClickCapture);
|
||||
click.setListener(buttonRef.current, onClick);
|
||||
clickCapture.setListener(buttonRef.current, onClickCapture);
|
||||
});
|
||||
|
||||
return (
|
||||
<TestScope ref={scopeRef}>
|
||||
<button ref={buttonRef}>
|
||||
<div
|
||||
ref={divRef}
|
||||
onClick={onClick}
|
||||
onClickCapture={onClickCapture}>
|
||||
Click me!
|
||||
</div>
|
||||
</button>
|
||||
</TestScope>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<Test />, container);
|
||||
Scheduler.unstable_flushAll();
|
||||
|
||||
const buttonElement = buttonRef.current;
|
||||
dispatchClickEvent(buttonElement);
|
||||
|
||||
expect(onClick).toHaveBeenCalledTimes(2);
|
||||
expect(onClickCapture).toHaveBeenCalledTimes(2);
|
||||
expect(log).toEqual([
|
||||
['capture', buttonElement],
|
||||
['capture', buttonElement],
|
||||
['bubble', buttonElement],
|
||||
['bubble', buttonElement],
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
onClick.mockClear();
|
||||
onClickCapture.mockClear();
|
||||
|
||||
const divElement = divRef.current;
|
||||
dispatchClickEvent(divElement);
|
||||
|
||||
expect(onClick).toHaveBeenCalledTimes(3);
|
||||
expect(onClickCapture).toHaveBeenCalledTimes(3);
|
||||
expect(log).toEqual([
|
||||
['capture', buttonElement],
|
||||
['capture', buttonElement],
|
||||
['capture', divElement],
|
||||
['bubble', divElement],
|
||||
['bubble', buttonElement],
|
||||
['bubble', buttonElement],
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@@ -11,19 +11,13 @@ import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
|
||||
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
|
||||
import type {ReactSyntheticEvent} from 'legacy-events/ReactSyntheticEventType';
|
||||
|
||||
import {
|
||||
HostComponent,
|
||||
ScopeComponent,
|
||||
} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {enableUseEventAPI, enableScopeAPI} from 'shared/ReactFeatureFlags';
|
||||
import {HostComponent} from 'react-reconciler/src/ReactWorkTags';
|
||||
import {enableUseEventAPI} from 'shared/ReactFeatureFlags';
|
||||
|
||||
import getListener from 'legacy-events/getListener';
|
||||
import {getListenersFromTarget} from '../client/ReactDOMComponentTree';
|
||||
import {IS_TARGET_EVENT_ONLY} from 'legacy-events/EventSystemFlags';
|
||||
import {
|
||||
eventTargetEventListenerStore,
|
||||
reactScopeListenerStore,
|
||||
} from './DOMModernPluginEventSystem';
|
||||
import {eventTargetEventListenerStore} from './DOMModernPluginEventSystem';
|
||||
|
||||
export default function accumulateTwoPhaseListeners(
|
||||
event: ReactSyntheticEvent,
|
||||
@@ -82,13 +76,11 @@ export default function accumulateTwoPhaseListeners(
|
||||
// usual two phase accumulation using the React fiber tree to pick up
|
||||
// all relevant useEvent and on* prop events.
|
||||
let node = event._targetInst;
|
||||
let lastHostComponent;
|
||||
|
||||
// Accumulate all instances and listeners via the target -> root path.
|
||||
while (node !== null) {
|
||||
// Handle listeners that are on HostComponents (i.e. <div>)
|
||||
// We only care for listeners that are on HostComponents (i.e. <div>)
|
||||
if (node.tag === HostComponent) {
|
||||
lastHostComponent = node.stateNode;
|
||||
// For useEvent listenrs
|
||||
if (enableUseEventAPI && accumulateUseEventListeners) {
|
||||
// useEvent event listeners
|
||||
@@ -135,30 +127,6 @@ export default function accumulateTwoPhaseListeners(
|
||||
dispatchInstances.push(node);
|
||||
}
|
||||
}
|
||||
} else if (enableScopeAPI && node.tag === ScopeComponent) {
|
||||
const reactScope = node.stateNode.methods;
|
||||
const eventTypeMap = reactScopeListenerStore.get(reactScope);
|
||||
if (eventTypeMap !== undefined) {
|
||||
const type = ((event.type: any): DOMTopLevelEventType);
|
||||
const listeners = eventTypeMap.get(type);
|
||||
if (listeners !== undefined) {
|
||||
const captureListeners = Array.from(listeners.captured);
|
||||
const bubbleListeners = Array.from(listeners.bubbled);
|
||||
|
||||
for (let i = 0; i < captureListeners.length; i++) {
|
||||
const listener = captureListeners[i];
|
||||
const {callback} = listener;
|
||||
dispatchListeners.unshift(callback);
|
||||
dispatchInstances.unshift(((lastHostComponent: any): Element));
|
||||
}
|
||||
for (let i = 0; i < bubbleListeners.length; i++) {
|
||||
const listener = bubbleListeners[i];
|
||||
const {callback} = listener;
|
||||
dispatchListeners.push(callback);
|
||||
dispatchInstances.push(((lastHostComponent: any): Element));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node.return;
|
||||
}
|
||||
|
||||
+2
-6
@@ -12,7 +12,6 @@ import type {
|
||||
ReactEventResponder,
|
||||
ReactEventResponderInstance,
|
||||
EventPriority,
|
||||
ReactScopeMethods,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {DOMTopLevelEventType} from 'legacy-events/TopLevelEventTypes';
|
||||
|
||||
@@ -87,15 +86,12 @@ export type ReactDOMListenerEvent = {|
|
||||
|
||||
export type ReactDOMListenerMap = {|
|
||||
clear: () => void,
|
||||
setListener: (
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
callback: ?(Event) => void,
|
||||
) => void,
|
||||
setListener: (target: EventTarget, callback: ?(Event) => void) => void,
|
||||
|};
|
||||
|
||||
export type ReactDOMListener = {|
|
||||
callback: Event => void,
|
||||
destroy: Node => void,
|
||||
event: ReactDOMListenerEvent,
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
target: EventTarget,
|
||||
|};
|
||||
|
||||
+3
-10
@@ -14,7 +14,6 @@ import type {
|
||||
ReactEventResponder,
|
||||
ReactContext,
|
||||
ReactEventResponderListener,
|
||||
ReactScopeMethods,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {Fiber} from './ReactFiber';
|
||||
import type {ExpirationTime} from './ReactFiberExpirationTime';
|
||||
@@ -1652,7 +1651,7 @@ function validateNotInFunctionRender(): boolean {
|
||||
function createReactListener(
|
||||
event: ReactListenerEvent,
|
||||
callback: Event => void,
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
target: EventTarget,
|
||||
destroy: Node => void,
|
||||
): ReactListener {
|
||||
return {
|
||||
@@ -1666,10 +1665,7 @@ function createReactListener(
|
||||
function mountEventListener(event: ReactListenerEvent): ReactListenerMap {
|
||||
if (enableUseEventAPI) {
|
||||
const hook = mountWorkInProgressHook();
|
||||
const listenerMap: Map<
|
||||
EventTarget | ReactScopeMethods,
|
||||
ReactListener,
|
||||
> = new Map();
|
||||
const listenerMap: Map<EventTarget, ReactListener> = new Map();
|
||||
const rootContainerInstance = getRootHostContainer();
|
||||
|
||||
// Register the event to the current root to ensure event
|
||||
@@ -1704,10 +1700,7 @@ function mountEventListener(event: ReactListenerEvent): ReactListenerMap {
|
||||
|
||||
const reactListenerMap: ReactListenerMap = {
|
||||
clear,
|
||||
setListener(
|
||||
target: EventTarget | ReactScopeMethods,
|
||||
callback: ?(Event) => void,
|
||||
): void {
|
||||
setListener(target: EventTarget, callback: ?(Event) => void): void {
|
||||
if (
|
||||
validateNotInFunctionRender() &&
|
||||
validateEventListenerTarget(target, callback)
|
||||
|
||||
@@ -26,7 +26,7 @@ export const disableInputAttributeSyncing = false;
|
||||
export const enableDeprecatedFlareAPI = true;
|
||||
export const enableFundamentalAPI = false;
|
||||
export const enableScopeAPI = true;
|
||||
export const enableUseEventAPI = true;
|
||||
export const enableUseEventAPI = false;
|
||||
export const warnAboutUnmockedScheduler = true;
|
||||
export const flushSuspenseFallbacksInTests = true;
|
||||
export const enableSuspenseCallback = true;
|
||||
|
||||
@@ -26,7 +26,7 @@ export const enableSchedulerDebugging = false;
|
||||
export const enableDeprecatedFlareAPI = true;
|
||||
export const enableFundamentalAPI = false;
|
||||
export const enableScopeAPI = true;
|
||||
export const enableUseEventAPI = true;
|
||||
export const enableUseEventAPI = false;
|
||||
export const warnAboutUnmockedScheduler = true;
|
||||
export const flushSuspenseFallbacksInTests = true;
|
||||
export const enableSuspenseCallback = true;
|
||||
|
||||
@@ -57,7 +57,7 @@ export const enableFundamentalAPI = false;
|
||||
|
||||
export const enableScopeAPI = true;
|
||||
|
||||
export const enableUseEventAPI = true;
|
||||
export const enableUseEventAPI = false;
|
||||
|
||||
export const warnAboutUnmockedScheduler = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user