Skip to content

Instantly share code, notes, and snippets.

@itsMapleLeaf
Last active November 14, 2023 08:06
Show Gist options
  • Save itsMapleLeaf/4c17662657f6c0f79f9f76bb34090625 to your computer and use it in GitHub Desktop.
Save itsMapleLeaf/4c17662657f6c0f79f9f76bb34090625 to your computer and use it in GitHub Desktop.
autoRef: make it so a component receives the ref as a normal prop
import type { ForwardedRef, ReactElement } from "react"
import { forwardRef } from "react"
/** Passes ref as a normal prop, makes `forwardRef`ing easier in some cases */
export function autoRef<Props extends { ref?: RefType }, RefType>(fc: {
(props: Props): ReactElement | null
displayName?: string
}) {
const AutoRef = (props: Props, ref: ForwardedRef<RefType>) =>
fc({ ...props, ref })
AutoRef.displayName = fc.displayName || fc.name || "AutoRef"
return forwardRef(AutoRef)
}
// before
import { ComponentPropsWithoutRef, forwardRef, ReactNode, Ref } from "react"
export default forwardRef(function ExternalLink(
{
href,
children,
...props
}: ComponentPropsWithoutRef<"a"> & { href: string; children: ReactNode },
ref: Ref<HTMLAnchorElement>,
) {
return (
<a
href={href}
target="_blank"
rel="noopener noreferrer"
{...props}
ref={ref}
>
{children}
</a>
)
})
// after
import type { ComponentProps, ReactNode } from "react"
import { autoRef } from "../react/helpers"
export default autoRef(function ExternalLink({
href,
children,
...props
}: ComponentProps<"a"> & { href: string; children: ReactNode }) {
return (
<a href={href} target="_blank" rel="noopener noreferrer" {...props}>
{children}
</a>
)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment