Nowoczesne komponenty generyczne Reacta
Programming
3/1/2024
3 minutes
Author: Dawid

Available languages:

Nowoczesne komponenty generyczne Reacta



Istnieje wiele sposobów na tworzenie komponentów wielokrotnego użytku w React. Począwszy od zbyt dobrze znanej klasy dającej, np: ".button" jako klasy css poprzedzonej ".button-secondary" itd. Ale czy są one odpowiednie dla nowoczesnego Reacta i dużych projektów?

W tym artykule chciałbym przedstawić najlepszą, najbardziej zoptymalizowaną i obecnie znaną mi metodę tworzenia generycznych komponentów na przykładzie przycisku.

W tym konkretnym przykładzie użyłem next.js jako projektu startowego. Do stworzenia naszego projektu będziemy potrzebować kilku bibliotek. Pierwszą z nich będzie dobrze znany TailwindCSS. Jest ona niezbędna do przypisania klas w naszym nowym komponencie generycznym. Następnie musimy stworzyć funkcję pomocniczą o nazwie "cn":

import { clsx } from "clsx"
import type { ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}


Aby działał poprawnie, z nowym komponentem Button musimy zainstalować następujące elementy: npm i clsx tailwind-merge class-variance-authority

Teraz możemy przystąpić do tworzenia naszego generycznego komponentu Button. Stworzymy go przy użyciu biblioteki "class-variance-authority". Pozwoli nam to tworzyć różne warianty przycisków, do których możemy przypisać klasy TailwindCSS.

import * as React from "react";
import { cva } from "class-variance-authority";
import type { VariantProps } from "class-variance-authority";

import { cn } from "@/utils/cn";

const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-base font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-orange-300 text-white hover:bg-orange-400",
secondary: "bg-blue-300 text-white hover:bg-blue-400",
ghost:
"border-orange-300 border-2 roundend-sm text-orange-300 hover:border-blue-400 hover:text-blue-400",
},
size: {
default: "px-4 py-2",
sm: "p-2 text-sm",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, ...props }, ref) => {
const Comp = "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";

export { Button, buttonVariants };


Korzystając z funkcji cva, możemy nadać naszemu komponentowi różne warianty, od "default, secondary, ghost" po bardziej ogólne warianty, takie jak "sizes". Na koniec musimy nadać naszemu komponentowi interfejs dla type-safety. Dzięki temu korzystanie z naszego ogólnego komponentu będzie proste i intuicyjne w całym projekcie.

Ostatni krok obejmuje kwestię wykorzystania naszego nowego komponentu. I jest to banalnie proste. Tutaj wystarczy zaimportować komponent Button z naszego zbudowanego komponentu i jest on gotowy do użycia:

<Button variant="default">Default</Button>

Lub jeśli chcemy użyć innego wariantu:

<Button variant="secondary">Secondary</Button>

Cały kod można znaleźć na moim githubie: https://github.com/shadown125/react-generic-components Jeśli masz jakieś pytania lub opinie, napisz komentarz!

About the author

avatar

Penify creator, Fullstack developer, Typescript, Web, Apps, Blogger

I am an experienced Fullstack web developer and the creator of Penify blog platform. I am excited and motivated to explore new technologies. I am a dedicated and hardworking person with a will to create the best user experience.

components
js
next.js
react
tailwind
tailwind-merge
ts

Comments

Be the first to comment on this article!