fix: avoid relying on Function.prototype.name to detect react components (#13931)

### What

Remove references to the `.name` property in the logic for detecting
react components. Instead just rely on `typeof` and `length`.

### Why

Don't use the presence/absence of function names to detect react
components or to distinguish client vs server components.

minifiers generally do not preserve function names. e.g. in swc
[`keepFnNames` is false by
default](https://swc.rs/docs/configuration/minification#:~:text=with%20terser.-,keepFnNames,-%2C%20Defaults%20to%20false).

A recent
[PR](ba227046ef)
in Next.js optimized the representation of esm exports which meant that
many `export function Foo` declarations would loose their names. This
broke users of payloadcms since now server props were no longer
propagated to their components due to the check
[here](c2300059a6/packages/ui/src/elements/withMergedProps/index.tsx (L43)).
This commit is contained in:
Luke Sandberg
2025-09-25 14:08:06 -07:00
committed by GitHub
parent 71c684e72e
commit 4652bd04d8

View File

@@ -5,31 +5,17 @@ const clientRefSymbol = Symbol.for('react.client.reference')
export function isReactServerComponentOrFunction<T extends any>(
component: any | React.ComponentType,
): component is T {
if (component === null || component === undefined) {
return false
}
const hasClientComponentSymbol = component.$$typeof == clientRefSymbol
const isFunctionalComponent = typeof component === 'function'
// Anonymous functions are Client Components in Turbopack. RSCs should have a name
const isAnonymousFunction = typeof component === 'function' && component.name === ''
const isRSC = isFunctionalComponent && !isAnonymousFunction && !hasClientComponentSymbol
return isRSC
return typeof component === 'function' && component.$$typeof !== clientRefSymbol
}
export function isReactClientComponent<T extends any>(
component: any | React.ComponentType,
): component is T {
if (component === null || component === undefined) {
return false
}
return !isReactServerComponentOrFunction(component) && component.$$typeof == clientRefSymbol
return typeof component === 'function' && component.$$typeof === clientRefSymbol
}
export function isReactComponentOrFunction<T extends any>(
component: any | React.ComponentType,
): component is T {
return isReactServerComponentOrFunction(component) || isReactClientComponent(component)
return typeof component === 'function'
}