最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Children.map replace svg - Stack Overflow

programmeradmin2浏览0评论

I would like to create a generic component that replaces the svgs inside a Button (shadcn) with a LoaderIcon (lucid-react). So sometimes it works, but sometimes not.

When it doesn't work, it is mostly because child.type resolves to this :

Here is my current component :

export function ConfirmedActionButton<T>({
  action,
  actionParams,
  children,
  confirmOptions = {},
  onSuccess,
  ...props
}: ButtonProps & {
  action: (data: T) => Promise<FormActionState>
  actionParams: T
  confirmOptions?: ConfirmOptions
  onSuccess?: () => void
}) {
  const [isPending, startTransition] = useTransition()

  const onConfirm = async () => {
    const { ok } = await safeConfirm(confirmOptions)

    if (ok) {
      startTransition(async () => {
        const res = await action(actionParams)
        if (res?.error) {
          toast.error("Une erreur est survenue.", { description: res.error })
        }

        if (res?.success) {
          toast.success(res?.success)
          onSuccess?.()
        }
      })
    }
  }

  const filteredChildren = useMemo(
    () =>
      Children.map(children, (child) => {
        if (isValidElement(child) && child.type === "svg") {
          return isPending ? <Loader2Icon className="animate-spin" /> : child
        }

        return child
      }),
    [children, isPending]
  )

  return (
    <Button {...props} onClick={onConfirm} disabled={isPending}>
      {filteredChildren}
    </Button>
  )
}

the components usage :

<ConfirmedActionButton
  className="absolute top-1.5 right-1.5 text-destructive rounded-full p-1"
  size={"icon"}
  variant={"ghost"}
  action={deleteAction}
  actionParams={asset.id}
>
  <span className="sr-only">Delete asset</span>
  <TrashIcon className="duration-200 ease-in-out" />
</ConfirmedActionButton>
发布评论

评论列表(0)

  1. 暂无评论