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:
@@ -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'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user