pnpm lint
> eslint .
.../frontend/components/animate-ui/primitives/animate/slot.tsx
86:6 error Error: Cannot create components during render
Components created during render will reset their state each time they are created. Declare components outside of render.
.../frontend/components/animate-ui/primitives/animate/slot.tsx:86:6
84 |
85 | return (
> 86 | <Base {...mergedProps} ref={mergeRefs(childRef as React.Ref<T>, ref)} />
| ^^^^ This component is created during render
87 | );
88 | }
89 |
.../frontend/components/animate-ui/primitives/animate/slot.tsx:75:11
73 | isAlreadyMotion
74 | ? (children.type as React.ElementType)
> 75 | : motion.create(children.type as React.ElementType),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The component is created during render here
76 | [isAlreadyMotion, children.type],
77 | );
78 | react-hooks/static-components
'use client';
import * as React from 'react';
import { motion, isMotionComponent, type HTMLMotionProps } from 'motion/react';
import { cn } from '@/lib/utils';
type AnyProps = Record<string, unknown>;
type DOMMotionProps<T extends HTMLElement = HTMLElement> = Omit<
HTMLMotionProps<keyof HTMLElementTagNameMap>,
'ref'
> & { ref?: React.Ref<T> };
type WithAsChild<Base extends object> =
| (Base & { asChild: true; children: React.ReactElement })
| (Base & { asChild?: false | undefined });
type SlotProps<T extends HTMLElement = HTMLElement> = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
children?: any;
} & DOMMotionProps<T>;
function mergeRefs<T>(
...refs: (React.Ref<T> | undefined)[]
): React.RefCallback<T> {
return (node) => {
refs.forEach((ref) => {
if (!ref) return;
if (typeof ref === 'function') {
ref(node);
} else {
(ref as React.RefObject<T | null>).current = node;
}
});
};
}
function mergeProps<T extends HTMLElement>(
childProps: AnyProps,
slotProps: DOMMotionProps<T>,
): AnyProps {
const merged: AnyProps = { ...childProps, ...slotProps };
if (childProps.className || slotProps.className) {
merged.className = cn(
childProps.className as string,
slotProps.className as string,
);
}
if (childProps.style || slotProps.style) {
merged.style = {
...(childProps.style as React.CSSProperties),
...(slotProps.style as React.CSSProperties),
};
}
return merged;
}
function Slot<T extends HTMLElement = HTMLElement>({
children,
ref,
...props
}: SlotProps<T>) {
const isAlreadyMotion =
typeof children.type === 'object' &&
children.type !== null &&
isMotionComponent(children.type);
const Base = React.useMemo(
() =>
isAlreadyMotion
? (children.type as React.ElementType)
: motion.create(children.type as React.ElementType),
[isAlreadyMotion, children.type],
);
if (!React.isValidElement(children)) return null;
const { ref: childRef, ...childProps } = children.props as AnyProps;
const mergedProps = mergeProps(childProps, props);
return (
<Base {...mergedProps} ref={mergeRefs(childRef as React.Ref<T>, ref)} />
);
}
export {
Slot,
type SlotProps,
type WithAsChild,
type DOMMotionProps,
type AnyProps,
};
Description
After upgrade to the latest React, the slot code gives the following error:
Code example
Concerned component
Slot
Additional context
React Version: 19.2.4