Skip to content

Commit

Permalink
[react-interactions] Remove context.setTimeout & context.clearTimeout (
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Oct 3, 2019
1 parent b33633d commit 4c56984
Show file tree
Hide file tree
Showing 7 changed files with 4 additions and 267 deletions.
92 changes: 1 addition & 91 deletions packages/react-dom/src/events/DOMEventResponderSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,6 @@ export function setListenToResponderEventTypes(
listenToResponderEventTypesImpl = _listenToResponderEventTypesImpl;
}

type ResponderTimeout = {|
id: TimeoutID,
timers: Map<number, ResponderTimer>,
|};

type ResponderTimer = {|
instance: ReactDOMEventResponderInstance,
func: () => void,
id: number,
timeStamp: number,
|};

const activeTimeouts: Map<number, ResponderTimeout> = new Map();
const rootEventTypesToEventResponderInstances: Map<
DOMTopLevelEventType | string,
Set<ReactDOMEventResponderInstance>,
Expand All @@ -80,9 +67,7 @@ const DoNotPropagateToNextResponder = 0;
const PropagateToNextResponder = 1;

let currentTimeStamp = 0;
let currentTimers = new Map();
let currentInstance: null | ReactDOMEventResponderInstance = null;
let currentTimerIDCounter = 0;
let currentDocument: null | Document = null;
let currentPropagationBehavior: PropagationBehavior = DoNotPropagateToNextResponder;

Expand Down Expand Up @@ -202,46 +187,6 @@ const eventResponderContext: ReactDOMResponderContext = {
}
}
},
setTimeout(func: () => void, delay): number {
validateResponderContext();
if (currentTimers === null) {
currentTimers = new Map();
}
let timeout = currentTimers.get(delay);

const timerId = currentTimerIDCounter++;
if (timeout === undefined) {
const timers = new Map();
const id = setTimeout(() => {
processTimers(timers, delay);
}, delay);
timeout = {
id,
timers,
};
currentTimers.set(delay, timeout);
}
timeout.timers.set(timerId, {
instance: ((currentInstance: any): ReactDOMEventResponderInstance),
func,
id: timerId,
timeStamp: currentTimeStamp,
});
activeTimeouts.set(timerId, timeout);
return timerId;
},
clearTimeout(timerId: number): void {
validateResponderContext();
const timeout = activeTimeouts.get(timerId);

if (timeout !== undefined) {
const timers = timeout.timers;
timers.delete(timerId);
if (timers.size === 0) {
clearTimeout(timeout.id);
}
}
},
getActiveDocument,
objectAssign: Object.assign,
getTimeStamp(): number {
Expand Down Expand Up @@ -340,33 +285,6 @@ function getActiveDocument(): Document {
return ((currentDocument: any): Document);
}

function processTimers(
timers: Map<number, ResponderTimer>,
delay: number,
): void {
const timersArr = Array.from(timers.values());
const previousInstance = currentInstance;
const previousTimers = currentTimers;
try {
batchedEventUpdates(() => {
for (let i = 0; i < timersArr.length; i++) {
const {instance, func, id, timeStamp} = timersArr[i];
currentInstance = instance;
currentTimeStamp = timeStamp + delay;
try {
func();
} finally {
activeTimeouts.delete(id);
}
}
});
} finally {
currentTimers = previousTimers;
currentInstance = previousInstance;
currentTimeStamp = 0;
}
}

function createDOMResponderEvent(
topLevelType: string,
nativeEvent: AnyNativeEvent,
Expand Down Expand Up @@ -510,15 +428,13 @@ export function mountEventResponder(
const onMount = responder.onMount;
if (onMount !== null) {
const previousInstance = currentInstance;
const previousTimers = currentTimers;
currentInstance = responderInstance;
try {
batchedEventUpdates(() => {
onMount(eventResponderContext, props, state);
});
} finally {
currentInstance = previousInstance;
currentTimers = previousTimers;
}
}
}
Expand All @@ -531,15 +447,13 @@ export function unmountEventResponder(
if (onUnmount !== null) {
let {props, state} = responderInstance;
const previousInstance = currentInstance;
const previousTimers = currentTimers;
currentInstance = responderInstance;
try {
batchedEventUpdates(() => {
onUnmount(eventResponderContext, props, state);
});
} finally {
currentInstance = previousInstance;
currentTimers = previousTimers;
}
}
const rootEventTypesSet = responderInstance.rootEventTypes;
Expand All @@ -561,8 +475,7 @@ export function unmountEventResponder(
function validateResponderContext(): void {
invariant(
currentInstance !== null,
'An event responder context was used outside of an event cycle. ' +
'Use context.setTimeout() to use asynchronous responder context outside of event cycle .',
'An event responder context was used outside of an event cycle.',
);
}

Expand All @@ -575,12 +488,10 @@ export function dispatchEventForResponderEventSystem(
): void {
if (enableFlareAPI) {
const previousInstance = currentInstance;
const previousTimers = currentTimers;
const previousTimeStamp = currentTimeStamp;
const previousDocument = currentDocument;
const previousPropagationBehavior = currentPropagationBehavior;
currentPropagationBehavior = DoNotPropagateToNextResponder;
currentTimers = null;
// nodeType 9 is DOCUMENT_NODE
currentDocument =
(nativeEventTarget: any).nodeType === 9
Expand All @@ -599,7 +510,6 @@ export function dispatchEventForResponderEventSystem(
);
});
} finally {
currentTimers = previousTimers;
currentInstance = previousInstance;
currentTimeStamp = previousTimeStamp;
currentDocument = previousDocument;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,81 +469,6 @@ describe('DOMEventResponderSystem', () => {
expect(eventLog).toEqual(['magic event fired', 'magicclick', 'bubble']);
});

it('async event dispatching works', () => {
let eventLog = [];
const buttonRef = React.createRef();

function handleEvent(event, context, props, phase) {
const pressEvent = {
target: event.target,
type: 'press',
phase,
timeStamp: context.getTimeStamp(),
};
context.dispatchEvent(pressEvent, props.onPress, DiscreteEvent);

context.setTimeout(() => {
const longPressEvent = {
target: event.target,
type: 'longpress',
phase,
timeStamp: context.getTimeStamp(),
};
context.dispatchEvent(longPressEvent, props.onLongPress, DiscreteEvent);

const longPressChangeEvent = {
target: event.target,
type: 'longpresschange',
phase,
timeStamp: context.getTimeStamp(),
};
context.dispatchEvent(
longPressChangeEvent,
props.onLongPressChange,
DiscreteEvent,
);
}, 500);
}

const TestResponder = createEventResponder({
targetEventTypes: ['click'],
onEvent: (event, context, props) => {
handleEvent(event, context, props, 'bubble');
},
});

function log(msg) {
eventLog.push(msg);
}

const Test = () => {
const listener = React.unstable_useResponder(TestResponder, {
onPress: e => log('press ' + e.phase),
onLongPress: e => log('longpress ' + e.phase),
onLongPressChange: e => log('longpresschange ' + e.phase),
});

return (
<button ref={buttonRef} listeners={listener}>
Click me!
</button>
);
};

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

// Clicking the button should trigger the event responder onEvent()
let buttonElement = buttonRef.current;
dispatchClickEvent(buttonElement);
jest.runAllTimers();

expect(eventLog).toEqual([
'press bubble',
'longpress bubble',
'longpresschange bubble',
]);
});

it('the event responder onMount() function should fire', () => {
let onMountFired = 0;

Expand Down
9 changes: 0 additions & 9 deletions packages/react-interactions/events/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ Defines the DOM events to listen to on the root of the app.

Defines the DOM events to listen to within the Event Responder subtree.


## ResponderContext

The Event Responder Context is exposed via the `context` argument for certain methods
Expand All @@ -78,10 +77,6 @@ on the `EventResponder` object.
This can be used to dynamically listen to events on the root of the app only
when it is necessary to do so.

### clearTimeout(id: Symbol): void

Clear a timeout defined using `context.setTimeout`.

### dispatchEvent(propName: string, event: CustomEvent, { discrete: boolean })

Dispatches a custom synthetic event. The `type` and `target` are required
Expand Down Expand Up @@ -109,7 +104,3 @@ is within the scope of the same responder, but owned by another Event Responder
### removeRootEventTypes(eventTypes: Array<ResponderEventType>)

Remove the root event types added with `addRootEventTypes`.

### setTimeout(func: () => void, delay: number): Symbol

This can be used to dispatch async events, e.g., those that fire after a delay.
Loading

0 comments on commit 4c56984

Please sign in to comment.