Ant Design 완벽 가이드 | React UI 라이브러리·Enterprise·테마·실전 활용
이 글의 핵심
Ant Design으로 엔터프라이즈 UI를 구축하는 완벽 가이드입니다. Components, Form, Table, Theming, TypeScript까지 실전 예제로 정리했습니다.
실무 경험 공유: 관리자 대시보드를 Ant Design으로 구축하면서, 개발 시간이 60% 단축되고 일관된 UX를 제공할 수 있었던 경험을 공유합니다.
들어가며: “엔터프라이즈 UI가 필요해요”
실무 문제 시나리오
시나리오 1: 관리자 대시보드를 만들어야 해요
복잡한 Table, Form이 필요합니다. Ant Design은 엔터프라이즈에 최적화되어 있습니다.
시나리오 2: 데이터 테이블이 필요해요
직접 만들기 어렵습니다. Ant Design Table은 강력합니다.
시나리오 3: 중국 시장을 타겟팅해요
중국어 지원이 필요합니다. Ant Design은 중국어가 기본입니다.
1. Ant Design이란?
핵심 특징
Ant Design은 엔터프라이즈 React UI 라이브러리입니다.
주요 장점:
- 엔터프라이즈: 복잡한 UI
- 50+ 컴포넌트: 풍부한 컴포넌트
- 강력한 Table: 정렬, 필터, 페이징
- Form: 복잡한 검증
- 국제화: 다국어 지원
2. 설치 및 설정
설치
npm install antd
기본 사용
import { Button, Space } from 'antd';
export default function App() {
return (
<Space>
<Button type="primary">Primary</Button>
<Button>Default</Button>
<Button type="dashed">Dashed</Button>
<Button type="link">Link</Button>
</Space>
);
}
3. Layout
import { Layout, Menu } from 'antd';
const { Header, Sider, Content, Footer } = Layout;
export default function AppLayout() {
return (
<Layout style={{ minHeight: '100vh' }}>
<Header>
<div style={{ color: 'white' }}>My App</div>
</Header>
<Layout>
<Sider>
<Menu
mode="inline"
items={[
{ key: '1', label: 'Dashboard' },
{ key: '2', label: 'Users' },
{ key: '3', label: 'Settings' },
]}
/>
</Sider>
<Content style={{ padding: '24px' }}>
{/* 콘텐츠 */}
</Content>
</Layout>
<Footer style={{ textAlign: 'center' }}>
My App ©2026
</Footer>
</Layout>
);
}
4. Form
import { Form, Input, Button, Checkbox } from 'antd';
interface FormData {
email: string;
password: string;
remember: boolean;
}
export default function LoginForm() {
const [form] = Form.useForm();
const onFinish = (values: FormData) => {
console.log('Success:', values);
};
return (
<Form
form={form}
name="login"
onFinish={onFinish}
autoComplete="off"
style={{ maxWidth: 400 }}
>
<Form.Item
name="email"
rules={[
{ required: true, message: 'Please input your email!' },
{ type: 'email', message: 'Please enter a valid email!' },
]}
>
<Input placeholder="Email" />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: 'Please input your password!' }]}
>
<Input.Password placeholder="Password" />
</Form.Item>
<Form.Item name="remember" valuePropName="checked">
<Checkbox>Remember me</Checkbox>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" block>
Submit
</Button>
</Form.Item>
</Form>
);
}
5. Table
import { Table } from 'antd';
import type { ColumnsType } from 'antd/es/table';
interface User {
id: number;
name: string;
email: string;
age: number;
}
const columns: ColumnsType<User> = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
sorter: (a, b) => a.name.localeCompare(b.name),
},
{
title: 'Email',
dataIndex: 'email',
key: 'email',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
sorter: (a, b) => a.age - b.age,
},
];
const data: User[] = [
{ id: 1, name: 'John', email: '[email protected]', age: 30 },
{ id: 2, name: 'Jane', email: '[email protected]', age: 25 },
];
export default function UserTable() {
return <Table columns={columns} dataSource={data} rowKey="id" />;
}
6. Theming
import { ConfigProvider } from 'antd';
const theme = {
token: {
colorPrimary: '#3498db',
colorSuccess: '#2ecc71',
colorWarning: '#f39c12',
colorError: '#e74c3c',
borderRadius: 8,
},
};
export default function App() {
return (
<ConfigProvider theme={theme}>
{/* 컴포넌트 */}
</ConfigProvider>
);
}
7. Icons
npm install @ant-design/icons
import { Button } from 'antd';
import { SendOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
export default function Icons() {
return (
<>
<Button type="primary" icon={<SendOutlined />}>
Send
</Button>
<Button danger icon={<DeleteOutlined />}>
Delete
</Button>
<Button icon={<PlusOutlined />}>Add</Button>
</>
);
}
8. Modal & Drawer
import { Button, Modal, Drawer } from 'antd';
import { useState } from 'react';
export default function ModalExample() {
const [isModalOpen, setIsModalOpen] = useState(false);
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
return (
<>
<Button onClick={() => setIsModalOpen(true)}>Open Modal</Button>
<Modal
title="Basic Modal"
open={isModalOpen}
onOk={() => setIsModalOpen(false)}
onCancel={() => setIsModalOpen(false)}
>
<p>Modal content</p>
</Modal>
<Button onClick={() => setIsDrawerOpen(true)}>Open Drawer</Button>
<Drawer
title="Basic Drawer"
placement="right"
onClose={() => setIsDrawerOpen(false)}
open={isDrawerOpen}
>
<p>Drawer content</p>
</Drawer>
</>
);
}
9. Message & Notification
import { Button, message, notification } from 'antd';
export default function Alerts() {
const showMessage = () => {
message.success('Success message');
};
const showNotification = () => {
notification.open({
message: 'Notification Title',
description: 'This is the content of the notification.',
placement: 'topRight',
});
};
return (
<>
<Button onClick={showMessage}>Show Message</Button>
<Button onClick={showNotification}>Show Notification</Button>
</>
);
}
10. 실전 예제: 사용자 관리
import { Table, Button, Space, Modal, Form, Input, message } from 'antd';
import { EditOutlined, DeleteOutlined } from '@ant-design/icons';
import { useState } from 'react';
interface User {
id: number;
name: string;
email: string;
}
export default function UserManagement() {
const [users, setUsers] = useState<User[]>([
{ id: 1, name: 'John', email: '[email protected]' },
{ id: 2, name: 'Jane', email: '[email protected]' },
]);
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingUser, setEditingUser] = useState<User | null>(null);
const [form] = Form.useForm();
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Email',
dataIndex: 'email',
key: 'email',
},
{
title: 'Actions',
key: 'actions',
render: (_, record: User) => (
<Space>
<Button
icon={<EditOutlined />}
onClick={() => {
setEditingUser(record);
form.setFieldsValue(record);
setIsModalOpen(true);
}}
>
Edit
</Button>
<Button
danger
icon={<DeleteOutlined />}
onClick={() => {
setUsers(users.filter((u) => u.id !== record.id));
message.success('User deleted');
}}
>
Delete
</Button>
</Space>
),
},
];
const handleSubmit = (values: Omit<User, 'id'>) => {
if (editingUser) {
setUsers(users.map((u) => (u.id === editingUser.id ? { ...u, ...values } : u)));
message.success('User updated');
} else {
setUsers([...users, { id: Date.now(), ...values }]);
message.success('User created');
}
setIsModalOpen(false);
setEditingUser(null);
form.resetFields();
};
return (
<>
<Button type="primary" onClick={() => setIsModalOpen(true)} style={{ mb: 4 }}>
Add User
</Button>
<Table columns={columns} dataSource={users} rowKey="id" />
<Modal
title={editingUser ? 'Edit User' : 'Add User'}
open={isModalOpen}
onCancel={() => {
setIsModalOpen(false);
setEditingUser(null);
form.resetFields();
}}
footer={null}
>
<Form form={form} onFinish={handleSubmit} layout="vertical">
<Form.Item
name="name"
label="Name"
rules={[{ required: true, message: 'Please input name!' }]}
>
<Input />
</Form.Item>
<Form.Item
name="email"
label="Email"
rules={[
{ required: true, message: 'Please input email!' },
{ type: 'email', message: 'Please enter a valid email!' },
]}
>
<Input />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" block>
{editingUser ? 'Update' : 'Create'}
</Button>
</Form.Item>
</Form>
</Modal>
</>
);
}
정리 및 체크리스트
핵심 요약
- Ant Design: 엔터프라이즈 UI 라이브러리
- 50+ 컴포넌트: 풍부한 컴포넌트
- 강력한 Table: 정렬, 필터, 페이징
- Form: 복잡한 검증
- 테마: 커스터마이징
- 국제화: 다국어 지원
구현 체크리스트
- Ant Design 설치
- 기본 컴포넌트 사용
- Layout 구성
- Form 구현
- Table 구현
- Theming 커스터마이징
- Icons 활용
- Modal & Drawer
같이 보면 좋은 글
- MUI 완벽 가이드
- React 완벽 가이드
- TypeScript 완벽 가이드
이 글에서 다루는 키워드
Ant Design, React, UI Library, Enterprise, Theming, TypeScript, Frontend
자주 묻는 질문 (FAQ)
Q. MUI와 비교하면 어떤가요?
A. Ant Design이 엔터프라이즈에 더 적합하고 Table이 강력합니다. MUI는 Material Design 기반입니다.
Q. 번들 크기는 어떤가요?
A. Tree-shakable이지만, 전체적으로 큰 편입니다.
Q. 중국어만 지원하나요?
A. 아니요, 40+ 언어를 지원합니다.
Q. 프로덕션에서 사용해도 되나요?
A. 네, Alibaba, Tencent 등 대기업에서 사용하고 있습니다.