Skip to content

Commit 3669b90

Browse files
authored
Event API: add more warnings for responder based events (#15597)
1 parent 05d0850 commit 3669b90

2 files changed

Lines changed: 119 additions & 8 deletions

File tree

packages/react-dom/src/events/DOMEventResponderSystem.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,20 +109,37 @@ const eventResponderContext: ReactResponderContext = {
109109
);
110110
}
111111
if (__DEV__) {
112-
possibleEventObject.preventDefault = () => {
113-
// Update this warning when we have a story around dealing with preventDefault
112+
const showWarning = name => {
114113
warning(
115114
false,
116-
'preventDefault() is no longer available on event objects created from event responder modules.',
115+
'%s is not available on event objects created from event responder modules (React Flare).',
116+
name,
117117
);
118118
};
119+
possibleEventObject.preventDefault = () => {
120+
showWarning('preventDefault()');
121+
};
119122
possibleEventObject.stopPropagation = () => {
120-
// Update this warning when we have a story around dealing with stopPropgation
121-
warning(
122-
false,
123-
'stopPropagation() is no longer available on event objects created from event responder modules.',
124-
);
123+
showWarning('stopPropagation()');
124+
};
125+
possibleEventObject.isDefaultPrevented = () => {
126+
showWarning('isDefaultPrevented()');
127+
};
128+
possibleEventObject.isPropagationStopped = () => {
129+
showWarning('isPropagationStopped()');
125130
};
131+
// $FlowFixMe: we don't need value, Flow thinks we do
132+
Object.defineProperty(possibleEventObject, 'nativeEvent', {
133+
get() {
134+
showWarning('nativeEvent');
135+
},
136+
});
137+
// $FlowFixMe: we don't need value, Flow thinks we do
138+
Object.defineProperty(possibleEventObject, 'defaultPrevented', {
139+
get() {
140+
showWarning('defaultPrevented');
141+
},
142+
});
126143
}
127144
const eventObject = ((possibleEventObject: any): $Shape<
128145
PartialEventObject,

packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,4 +889,98 @@ describe('DOMEventResponderSystem', () => {
889889

890890
ReactDOM.render(<Test />, container);
891891
});
892+
893+
it('the event responder system should warn on accessing invalid properties', () => {
894+
const ClickEventComponent = createReactEventComponent(
895+
undefined,
896+
['click'],
897+
undefined,
898+
undefined,
899+
undefined,
900+
(event, context, props) => {
901+
const syntheticEvent = {
902+
target: event.target,
903+
type: 'click',
904+
};
905+
context.dispatchEvent(syntheticEvent, props.onClick, {
906+
discrete: true,
907+
});
908+
},
909+
);
910+
911+
let handler;
912+
const Test = () => (
913+
<ClickEventComponent onClick={handler}>
914+
<button>Click me!</button>
915+
</ClickEventComponent>
916+
);
917+
expect(() => {
918+
handler = event => {
919+
event.preventDefault();
920+
};
921+
ReactDOM.render(<Test />, container);
922+
dispatchClickEvent(document.body);
923+
}).toWarnDev(
924+
'Warning: preventDefault() is not available on event objects created ' +
925+
'from event responder modules (React Flare).',
926+
{withoutStack: true},
927+
);
928+
expect(() => {
929+
handler = event => {
930+
event.stopPropagation();
931+
};
932+
ReactDOM.render(<Test />, container);
933+
dispatchClickEvent(document.body);
934+
}).toWarnDev(
935+
'Warning: stopPropagation() is not available on event objects created ' +
936+
'from event responder modules (React Flare).',
937+
{withoutStack: true},
938+
);
939+
expect(() => {
940+
handler = event => {
941+
event.isDefaultPrevented();
942+
};
943+
ReactDOM.render(<Test />, container);
944+
dispatchClickEvent(document.body);
945+
}).toWarnDev(
946+
'Warning: isDefaultPrevented() is not available on event objects created ' +
947+
'from event responder modules (React Flare).',
948+
{withoutStack: true},
949+
);
950+
expect(() => {
951+
handler = event => {
952+
event.isPropagationStopped();
953+
};
954+
ReactDOM.render(<Test />, container);
955+
dispatchClickEvent(document.body);
956+
}).toWarnDev(
957+
'Warning: isPropagationStopped() is not available on event objects created ' +
958+
'from event responder modules (React Flare).',
959+
{withoutStack: true},
960+
);
961+
expect(() => {
962+
handler = event => {
963+
return event.nativeEvent;
964+
};
965+
ReactDOM.render(<Test />, container);
966+
dispatchClickEvent(document.body);
967+
}).toWarnDev(
968+
'Warning: nativeEvent is not available on event objects created ' +
969+
'from event responder modules (React Flare).',
970+
{withoutStack: true},
971+
);
972+
expect(() => {
973+
handler = event => {
974+
return event.defaultPrevented;
975+
};
976+
ReactDOM.render(<Test />, container);
977+
dispatchClickEvent(document.body);
978+
}).toWarnDev(
979+
'Warning: defaultPrevented is not available on event objects created ' +
980+
'from event responder modules (React Flare).',
981+
{withoutStack: true},
982+
);
983+
984+
expect(container.innerHTML).toBe('<button>Click me!</button>');
985+
});
892986
});

0 commit comments

Comments
 (0)