将“props”传递给子组件并有条件地渲染它

问题描述 投票:0回答:1

这是我的

loginButton
,它是另一个文件中
Button
组件的包装。

'use client';

import { useRouter } from 'next/navigation';
import { useTransition } from 'react';

interface LoginButtonProps {
  children: React.ReactNode;
  mode?: 'modal' | 'redirect';
  asChild?: boolean;
}

export const LoginButton = ({
  children,
  mode = 'redirect',
  asChild,
}: LoginButtonProps) => {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();

  const onclickHandler = () => {
    router.push('/auth/login');
    console.log('clicked');
  };

  return (
    <span className="cursor-pointer" onClick={onclickHandler}>
      {children}
    </span>
  );
};

Button
分量是:

import { Button } from '@/components/ui/button';
import { LoginButton } from '@/components/auth/login-button';

export default function Home() {
  return (
    <main>
        <LoginButton>
          <Button variant="secondary" size="lg" className="mt-8">
            Sign in
          </Button>
        </LoginButton>
      </div>
    </main>
  );
}

我想将

isPending
状态作为 prop 传递并在
Home
组件内部使用。我想在
isPending
为 true 时保持按钮禁用并更改其文本。如何实现这一目标?

请用您宝贵的时间和知识帮助我。预先感谢。

reactjs typescript next.js react-props
1个回答
0
投票

您可以尝试将 fallback 组件传递给将在

transition
挂起时渲染的 LoginButton

登录按钮:

export const LoginButton = ({
  children,
  mode = 'redirect',
  asChild,
  fallback
}: LoginButtonProps) => {
  const router = useRouter();
  const [isPending, startTransition] = useTransition();

  const onclickHandler = () => {
    router.push('/auth/login');
    console.log('clicked');
  };

  return (
    <span className="cursor-pointer" onClick={onclickHandler}>
      {isPending ? fallback : children}
    </span>
  );
};

后备组件:

function LoadingBtn() {
 return (
   <Button variant="secondary" size="lg" className="mt-8" disabled>
      Loading
   </Button>
 )
}

实施:

<LoginButton fallback={<LoadingBtn />}>
          <Button variant="secondary" size="lg" className="mt-8">
            Sign in
          </Button>
</LoginButton>
© www.soinside.com 2019 - 2024. All rights reserved.