mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Use getComponentNameFromType for debug info for the key warning (#27930)
If this is a client reference we shouldn't dot into it, which would throw in the proxy. Interestingly our client references don't really have a `name` associated with them for debug information so a component type doesn't show up in error logs even though it seems like it should.
This commit is contained in:
committed by
GitHub
parent
6639ed3b3a
commit
0ac3ea471f
@@ -1009,6 +1009,22 @@ describe('ReactFlight', () => {
|
||||
ReactNoopFlightClient.read(transport);
|
||||
});
|
||||
|
||||
it('should warn in DEV a child is missing keys', () => {
|
||||
function ParentClient({children}) {
|
||||
return children;
|
||||
}
|
||||
const Parent = clientReference(ParentClient);
|
||||
expect(() => {
|
||||
const transport = ReactNoopFlightServer.render(
|
||||
<Parent>{Array(6).fill(<div>no key</div>)}</Parent>,
|
||||
);
|
||||
ReactNoopFlightClient.read(transport);
|
||||
}).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop. ' +
|
||||
'See https://reactjs.org/link/warning-keys for more information.',
|
||||
);
|
||||
});
|
||||
|
||||
it('should error if a class instance is passed to a host component', () => {
|
||||
class Foo {
|
||||
method() {}
|
||||
|
||||
@@ -590,6 +590,29 @@ describe('ReactFlightDOMBrowser', () => {
|
||||
expect(reportedErrors).toEqual(['for reasons']);
|
||||
});
|
||||
|
||||
it('should warn in DEV a child is missing keys', async () => {
|
||||
function ParentClient({children}) {
|
||||
return children;
|
||||
}
|
||||
const Parent = clientExports(ParentClient);
|
||||
const ParentModule = clientExports({Parent: ParentClient});
|
||||
await expect(async () => {
|
||||
const stream = ReactServerDOMServer.renderToReadableStream(
|
||||
<>
|
||||
<Parent>{Array(6).fill(<div>no key</div>)}</Parent>
|
||||
<ParentModule.Parent>
|
||||
{Array(6).fill(<div>no key</div>)}
|
||||
</ParentModule.Parent>
|
||||
</>,
|
||||
webpackMap,
|
||||
);
|
||||
await ReactServerDOMClient.createFromReadableStream(stream);
|
||||
}).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop. ' +
|
||||
'See https://reactjs.org/link/warning-keys for more information.',
|
||||
);
|
||||
});
|
||||
|
||||
it('basic use(promise)', async () => {
|
||||
function Server() {
|
||||
return (
|
||||
|
||||
@@ -96,10 +96,7 @@ function getCurrentComponentErrorInfo(parentType) {
|
||||
let info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
const parentName =
|
||||
typeof parentType === 'string'
|
||||
? parentType
|
||||
: parentType.displayName || parentType.name;
|
||||
const parentName = getComponentNameFromType(parentType);
|
||||
if (parentName) {
|
||||
info = `\n\nCheck the top-level render call using <${parentName}>.`;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,7 @@ function getCurrentComponentErrorInfo(parentType) {
|
||||
let info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
const parentName =
|
||||
typeof parentType === 'string'
|
||||
? parentType
|
||||
: parentType.displayName || parentType.name;
|
||||
const parentName = getComponentNameFromType(parentType);
|
||||
if (parentName) {
|
||||
info = `\n\nCheck the top-level render call using <${parentName}>.`;
|
||||
}
|
||||
|
||||
@@ -52,21 +52,19 @@ function getContextName(type: ReactContext<any>) {
|
||||
return type.displayName || 'Context';
|
||||
}
|
||||
|
||||
const REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference');
|
||||
|
||||
// Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
|
||||
export default function getComponentNameFromType(type: mixed): string | null {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (typeof (type: any).tag === 'number') {
|
||||
console.error(
|
||||
'Received an unexpected object in getComponentNameFromType(). ' +
|
||||
'This is likely a bug in React. Please file an issue.',
|
||||
);
|
||||
}
|
||||
}
|
||||
if (typeof type === 'function') {
|
||||
if ((type: any).$$typeof === REACT_CLIENT_REFERENCE) {
|
||||
// TODO: Create a convention for naming client references with debug info.
|
||||
return null;
|
||||
}
|
||||
return (type: any).displayName || type.name || null;
|
||||
}
|
||||
if (typeof type === 'string') {
|
||||
@@ -96,6 +94,14 @@ export default function getComponentNameFromType(type: mixed): string | null {
|
||||
}
|
||||
}
|
||||
if (typeof type === 'object') {
|
||||
if (__DEV__) {
|
||||
if (typeof (type: any).tag === 'number') {
|
||||
console.error(
|
||||
'Received an unexpected object in getComponentNameFromType(). ' +
|
||||
'This is likely a bug in React. Please file an issue.',
|
||||
);
|
||||
}
|
||||
}
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
const context: ReactContext<any> = (type: any);
|
||||
|
||||
Reference in New Issue
Block a user