Skip to content

Commit

Permalink
Experimental Event API: add event component mount phase callback (#15480
Browse files Browse the repository at this point in the history
)
  • Loading branch information
trueadm authored Apr 24, 2019
1 parent ce126fb commit d3af2f2
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 9 deletions.
18 changes: 17 additions & 1 deletion packages/react-dom/src/events/DOMEventResponderSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,10 @@ function triggerOwnershipListeners(): void {
const instance = listeningInstances[i];
const {props, responder, state} = instance;
currentInstance = instance;
responder.onOwnershipChange(eventResponderContext, props, state);
const onOwnershipChange = responder.onOwnershipChange;
if (onOwnershipChange !== undefined) {
onOwnershipChange(eventResponderContext, props, state);
}
}
} finally {
currentInstance = previousInstance;
Expand All @@ -626,6 +629,19 @@ export function mountEventResponder(
if (responder.onOwnershipChange !== undefined) {
ownershipChangeListeners.add(eventComponentInstance);
}
const onMount = responder.onMount;
if (onMount !== undefined) {
let {props, state} = eventComponentInstance;
currentEventQueue = createEventQueue();
currentInstance = eventComponentInstance;
try {
onMount(eventResponderContext, props, state);
} finally {
currentEventQueue = null;
currentInstance = null;
currentTimers = null;
}
}
}

export function unmountEventResponder(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ function createReactEventComponent(
onEvent,
onEventCapture,
onRootEvent,
onMount,
onUnmount,
onOwnershipChange,
stopLocalPropagation,
Expand All @@ -32,6 +33,7 @@ function createReactEventComponent(
onEvent,
onEventCapture,
onRootEvent,
onMount,
onUnmount,
onOwnershipChange,
stopLocalPropagation: stopLocalPropagation || false,
Expand Down Expand Up @@ -395,6 +397,7 @@ describe('DOMEventResponderSystem', () => {
undefined,
undefined,
undefined,
undefined,
true,
);

Expand Down Expand Up @@ -554,6 +557,31 @@ describe('DOMEventResponderSystem', () => {
]);
});

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

const EventComponent = createReactEventComponent(
[],
undefined,
undefined,
undefined,
undefined,
undefined,
() => {
onMountFired++;
},
);

const Test = () => (
<EventComponent>
<button />
</EventComponent>
);

ReactDOM.render(<Test />, container);
expect(onMountFired).toEqual(1);
});

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

Expand All @@ -563,7 +591,8 @@ describe('DOMEventResponderSystem', () => {
undefined,
undefined,
undefined,
(event, context, props, state) => {},
undefined,
undefined,
() => {
onUnmountFired++;
},
Expand Down Expand Up @@ -592,6 +621,7 @@ describe('DOMEventResponderSystem', () => {
undefined,
undefined,
undefined,
undefined,
(context, props, state) => {
counter += state.incrementAmount;
},
Expand Down Expand Up @@ -623,6 +653,7 @@ describe('DOMEventResponderSystem', () => {
undefined,
undefined,
undefined,
undefined,
() => {
onOwnershipChangeFired++;
},
Expand Down
9 changes: 8 additions & 1 deletion packages/react-reconciler/src/ReactFiberCommitWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import {
unhideTextInstance,
unmountEventComponent,
commitEventTarget,
mountEventComponent,
} from './ReactFiberHostConfig';
import {
captureCommitPhaseError,
Expand Down Expand Up @@ -595,6 +596,7 @@ function commitLifeCycles(
case SuspenseComponent:
case IncompleteClassComponent:
case EventTarget:
case EventComponent:
break;
default: {
invariant(
Expand Down Expand Up @@ -835,7 +837,8 @@ function commitContainer(finishedWork: Fiber) {
case ClassComponent:
case HostComponent:
case HostText:
case EventTarget: {
case EventTarget:
case EventComponent: {
return;
}
case HostRoot:
Expand Down Expand Up @@ -1255,6 +1258,10 @@ function commitWork(current: Fiber | null, finishedWork: Fiber): void {
case IncompleteClassComponent: {
return;
}
case EventComponent: {
mountEventComponent(finishedWork.stateNode);
return;
}
default: {
invariant(
false,
Expand Down
4 changes: 1 addition & 3 deletions packages/react-reconciler/src/ReactFiberCompleteWork.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ import {
createContainerChildSet,
appendChildToContainerChildSet,
finalizeContainerChildren,
mountEventComponent,
updateEventComponent,
handleEventTarget,
} from './ReactFiberHostConfig';
Expand Down Expand Up @@ -813,14 +812,13 @@ function completeWork(
responderState = responder.createInitialState(newProps);
}
eventComponentInstance = workInProgress.stateNode = {
context: null,
props: newProps,
responder,
rootEventTypes: null,
rootInstance: rootContainerInstance,
state: responderState,
};
mountEventComponent(eventComponentInstance);
markUpdate(workInProgress);
} else {
// Update the props on the event component state node
eventComponentInstance.props = newProps;
Expand Down
10 changes: 7 additions & 3 deletions packages/shared/ReactTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,24 @@ export type ReactEventResponder = {
props: null | Object,
state: null | Object,
) => void,
onUnmount: (
onMount?: (
context: ReactResponderContext,
props: null | Object,
state: null | Object,
) => void,
onOwnershipChange: (
onUnmount?: (
context: ReactResponderContext,
props: null | Object,
state: null | Object,
) => void,
onOwnershipChange?: (
context: ReactResponderContext,
props: null | Object,
state: null | Object,
) => void,
};

export type ReactEventComponentInstance = {|
context: null | Object,
props: null | Object,
responder: ReactEventResponder,
rootEventTypes: null | Set<string>,
Expand Down

0 comments on commit d3af2f2

Please sign in to comment.