Skip to content

Commit 89064fe

Browse files
authored
Adds displayName to EventComponent and EventTarget (#15268)
* Adds displayName to EventComponent and EventTarget
1 parent fc6a9f1 commit 89064fe

File tree

10 files changed

+183
-1
lines changed

10 files changed

+183
-1
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ function createReactEventComponent(targetEventTypes, handleEvent) {
2121

2222
return {
2323
$$typeof: Symbol.for('react.event_component'),
24+
displayName: 'TestEventComponent',
2425
props: null,
2526
responder: testEventResponder,
2627
};

packages/react-events/src/Drag.js

+1
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ const DragResponder = {
211211

212212
export default {
213213
$$typeof: REACT_EVENT_COMPONENT_TYPE,
214+
displayName: 'Drag',
214215
props: null,
215216
responder: DragResponder,
216217
};

packages/react-events/src/Focus.js

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const FocusResponder = {
122122

123123
export default {
124124
$$typeof: REACT_EVENT_COMPONENT_TYPE,
125+
displayName: 'Focus',
125126
props: null,
126127
responder: FocusResponder,
127128
};

packages/react-events/src/Hover.js

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ const HoverResponder = {
204204

205205
export default {
206206
$$typeof: REACT_EVENT_COMPONENT_TYPE,
207+
displayName: 'Hover',
207208
props: null,
208209
responder: HoverResponder,
209210
};

packages/react-events/src/Press.js

+1
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ const PressResponder = {
395395

396396
export default {
397397
$$typeof: REACT_EVENT_COMPONENT_TYPE,
398+
displayName: 'Press',
398399
props: null,
399400
responder: PressResponder,
400401
};

packages/react-events/src/Swipe.js

+1
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ const SwipeResponder = {
239239

240240
export default {
241241
$$typeof: REACT_EVENT_COMPONENT_TYPE,
242+
displayName: 'Swipe',
242243
props: null,
243244
responder: SwipeResponder,
244245
};

packages/react-events/src/__tests__/Press-test.internal.js

+4
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,8 @@ describe('Event responder: Press', () => {
394394
expect(events).toEqual(['keydown', 'inner: onPress', 'outer: onPress']);
395395
});
396396
});
397+
398+
it('expect displayName to show up for event component', () => {
399+
expect(Press.displayName).toBe('Press');
400+
});
397401
});

packages/react-reconciler/src/__tests__/ReactFiberEvents-test-internal.js

+148-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const noOpResponder = {
2929
function createReactEventComponent() {
3030
return {
3131
$$typeof: ReactSymbols.REACT_EVENT_COMPONENT_TYPE,
32+
displayName: 'TestEventComponent',
3233
props: null,
3334
responder: noOpResponder,
3435
};
@@ -37,6 +38,7 @@ function createReactEventComponent() {
3738
function createReactEventTarget() {
3839
return {
3940
$$typeof: ReactSymbols.REACT_EVENT_TARGET_TYPE,
41+
displayName: 'TestEventTarget',
4042
type: Symbol.for('react.event_target.test'),
4143
};
4244
}
@@ -392,6 +394,54 @@ describe('ReactFiberEvents', () => {
392394
'Warning: validateDOMNesting: React event targets must not have event components as children.',
393395
);
394396
});
397+
398+
it('should error with a component stack contains the names of the event components and event targets', () => {
399+
let componentStackMessage;
400+
401+
function ErrorComponent() {
402+
throw new Error('Failed!');
403+
}
404+
405+
const Test = () => (
406+
<EventComponent>
407+
<EventTarget>
408+
<span>
409+
<ErrorComponent />
410+
</span>
411+
</EventTarget>
412+
</EventComponent>
413+
);
414+
415+
class Wrapper extends React.Component {
416+
state = {
417+
error: null,
418+
};
419+
420+
componentDidCatch(error, errMessage) {
421+
componentStackMessage = errMessage.componentStack;
422+
this.setState({
423+
error,
424+
});
425+
}
426+
427+
render() {
428+
if (this.state.error) {
429+
return null;
430+
}
431+
return <Test />;
432+
}
433+
}
434+
435+
ReactNoop.render(<Wrapper />);
436+
expect(Scheduler).toFlushWithoutYielding();
437+
438+
expect(componentStackMessage.includes('ErrorComponent')).toBe(true);
439+
expect(componentStackMessage.includes('span')).toBe(true);
440+
expect(componentStackMessage.includes('TestEventTarget')).toBe(true);
441+
expect(componentStackMessage.includes('TestEventComponent')).toBe(true);
442+
expect(componentStackMessage.includes('Test')).toBe(true);
443+
expect(componentStackMessage.includes('Wrapper')).toBe(true);
444+
});
395445
});
396446

397447
describe('TestRenderer', () => {
@@ -570,7 +620,7 @@ describe('ReactFiberEvents', () => {
570620
error: null,
571621
};
572622

573-
componentDidCatch(error) {
623+
componentDidCatch(error, errStack) {
574624
this.setState({
575625
error,
576626
});
@@ -734,6 +784,55 @@ describe('ReactFiberEvents', () => {
734784
'Warning: validateDOMNesting: React event targets must not have event components as children.',
735785
);
736786
});
787+
788+
it('should error with a component stack contains the names of the event components and event targets', () => {
789+
let componentStackMessage;
790+
791+
function ErrorComponent() {
792+
throw new Error('Failed!');
793+
}
794+
795+
const Test = () => (
796+
<EventComponent>
797+
<EventTarget>
798+
<span>
799+
<ErrorComponent />
800+
</span>
801+
</EventTarget>
802+
</EventComponent>
803+
);
804+
805+
class Wrapper extends React.Component {
806+
state = {
807+
error: null,
808+
};
809+
810+
componentDidCatch(error, errMessage) {
811+
componentStackMessage = errMessage.componentStack;
812+
this.setState({
813+
error,
814+
});
815+
}
816+
817+
render() {
818+
if (this.state.error) {
819+
return null;
820+
}
821+
return <Test />;
822+
}
823+
}
824+
825+
const root = ReactTestRenderer.create(null);
826+
root.update(<Wrapper />);
827+
expect(Scheduler).toFlushWithoutYielding();
828+
829+
expect(componentStackMessage.includes('ErrorComponent')).toBe(true);
830+
expect(componentStackMessage.includes('span')).toBe(true);
831+
expect(componentStackMessage.includes('TestEventTarget')).toBe(true);
832+
expect(componentStackMessage.includes('TestEventComponent')).toBe(true);
833+
expect(componentStackMessage.includes('Test')).toBe(true);
834+
expect(componentStackMessage.includes('Wrapper')).toBe(true);
835+
});
737836
});
738837

739838
describe('ReactDOM', () => {
@@ -1053,6 +1152,54 @@ describe('ReactFiberEvents', () => {
10531152
'Warning: validateDOMNesting: React event targets must not have event components as children.',
10541153
);
10551154
});
1155+
1156+
it('should error with a component stack contains the names of the event components and event targets', () => {
1157+
let componentStackMessage;
1158+
1159+
function ErrorComponent() {
1160+
throw new Error('Failed!');
1161+
}
1162+
1163+
const Test = () => (
1164+
<EventComponent>
1165+
<EventTarget>
1166+
<span>
1167+
<ErrorComponent />
1168+
</span>
1169+
</EventTarget>
1170+
</EventComponent>
1171+
);
1172+
1173+
class Wrapper extends React.Component {
1174+
state = {
1175+
error: null,
1176+
};
1177+
1178+
componentDidCatch(error, errMessage) {
1179+
componentStackMessage = errMessage.componentStack;
1180+
this.setState({
1181+
error,
1182+
});
1183+
}
1184+
1185+
render() {
1186+
if (this.state.error) {
1187+
return null;
1188+
}
1189+
return <Test />;
1190+
}
1191+
}
1192+
1193+
const container = document.createElement('div');
1194+
ReactDOM.render(<Wrapper />, container);
1195+
1196+
expect(componentStackMessage.includes('ErrorComponent')).toBe(true);
1197+
expect(componentStackMessage.includes('span')).toBe(true);
1198+
expect(componentStackMessage.includes('TestEventTarget')).toBe(true);
1199+
expect(componentStackMessage.includes('TestEventComponent')).toBe(true);
1200+
expect(componentStackMessage.includes('Test')).toBe(true);
1201+
expect(componentStackMessage.includes('Wrapper')).toBe(true);
1202+
});
10561203
});
10571204

10581205
describe('ReactDOMServer', () => {

packages/shared/ReactTypes.js

+2
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,13 @@ export type ReactEventResponder = {
9393

9494
export type ReactEventComponent = {|
9595
$$typeof: Symbol | number,
96+
displayName?: string,
9697
props: null | Object,
9798
responder: ReactEventResponder,
9899
|};
99100

100101
export type ReactEventTarget = {|
101102
$$typeof: Symbol | number,
103+
displayName?: string,
102104
type: Symbol | number,
103105
|};

packages/shared/getComponentName.js

+23
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ import {
2222
REACT_STRICT_MODE_TYPE,
2323
REACT_SUSPENSE_TYPE,
2424
REACT_LAZY_TYPE,
25+
REACT_EVENT_COMPONENT_TYPE,
26+
REACT_EVENT_TARGET_TYPE,
27+
REACT_EVENT_TARGET_TOUCH_HIT,
2528
} from 'shared/ReactSymbols';
2629
import {refineResolvedLazyComponent} from 'shared/ReactLazyComponent';
30+
import type {ReactEventComponent, ReactEventTarget} from 'shared/ReactTypes';
2731

2832
function getWrappedName(
2933
outerType: mixed,
@@ -87,6 +91,25 @@ function getComponentName(type: mixed): string | null {
8791
if (resolvedThenable) {
8892
return getComponentName(resolvedThenable);
8993
}
94+
break;
95+
}
96+
case REACT_EVENT_COMPONENT_TYPE: {
97+
const eventComponent = ((type: any): ReactEventComponent);
98+
const displayName = eventComponent.displayName;
99+
if (displayName !== undefined) {
100+
return displayName;
101+
}
102+
break;
103+
}
104+
case REACT_EVENT_TARGET_TYPE: {
105+
const eventTarget = ((type: any): ReactEventTarget);
106+
if (eventTarget.type === REACT_EVENT_TARGET_TOUCH_HIT) {
107+
return 'TouchHitTarget';
108+
}
109+
const displayName = eventTarget.displayName;
110+
if (displayName !== undefined) {
111+
return displayName;
112+
}
90113
}
91114
}
92115
}

0 commit comments

Comments
 (0)