Skip to content

Component Reusability in React (การใช้งานคอมโพเนนต์ซ้ำใน React)

การออกแบบคอมโพเนนต์ให้ใช้ซ้ำได้ช่วยลดการซ้ำซ้อนของโค้ด

Props Design (ออกแบบ props อย่างมีประสิทธิภาพ)

tsx
interface ButtonProps {
  variant?: "primary" | "secondary" | "danger";
  size?: "sm" | "md" | "lg";
  children: React.ReactNode;
  onClick?: () => void;
  disabled?: boolean;
}

const Button: React.FC<ButtonProps> = ({
  variant = "primary",
  size = "md",
  children,
  onClick,
  disabled = false,
}) => {
  return (
    <button
      className={`btn-${variant} btn-${size}`}
      onClick={onClick}
      disabled={disabled}
    >
      {children}
    </button>
  );
};

Compound Components (คอมโพเนนต์แบบผสม)

tsx
const Card = ({ children }: { children: React.ReactNode }) => {
  return <div className="card">{children}</div>;
};

Card.Header = ({ title }: { title: string }) => (
  <div className="card-header">{title}</div>
);

Card.Body = ({ children }: { children: React.ReactNode }) => (
  <div className="card-body">{children}</div>
);

// วิธีใช้
<Card>
  <Card.Header title="หัวข้อ" />
  <Card.Body>
    เนื้อหาข้อความ
  </Card.Body>
</Card>;

Render Props Pattern

tsx
interface DataFetcherProps<T> {
  url: string;
  children: (data: T | null, loading: boolean) => React.ReactNode;
}

function DataFetcher<T>({ url, children }: DataFetcherProps<T>) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return children(data, loading);
}

// วิธีใช้
<DataFetcher url="/api/users">
  {(users, loading) => (
    loading ? <Spinner /> : <UserList users={users} />
  )}
</DataFetcher>;

หมายเหตุ

  • ออกแบบคอมโพเนนต์ให้มีความรับผิดชอบเดียว (Single Responsibility)
  • ใช้ TypeScript เพื่อความชัดเจนของ props
  • คิดถึง use cases ต่างๆ ที่จะนำคอมโพเนนต์ไปใช้