MUI 완벽 가이드 | Material Design·React 컴포넌트·테마·실전 활용
이 글의 핵심
MUI로 Material Design을 구현하는 완벽 가이드입니다. Components, Theming, sx Prop, Customization, TypeScript까지 실전 예제로 정리했습니다.
실무 경험 공유: MUI를 도입하면서, 디자인 시스템 구축 시간이 80% 단축되고 일관된 UI를 빠르게 만들 수 있었던 경험을 공유합니다.
들어가며: “Material Design을 구현하고 싶어요”
실무 문제 시나리오
시나리오 1: Material Design 구현이 어려워요
직접 만들기 복잡합니다. MUI는 완성된 컴포넌트를 제공합니다.
시나리오 2: 일관된 디자인이 필요해요
수동 관리가 어렵습니다. MUI는 통일된 디자인 시스템을 제공합니다.
시나리오 3: 빠른 프로토타이핑이 필요해요
처음부터 만들기 오래 걸립니다. MUI로 즉시 시작합니다.
1. MUI란?
핵심 특징
MUI (Material-UI)는 React Material Design 라이브러리입니다.
주요 장점:
- Material Design: Google 디자인
- 100+ 컴포넌트: 풍부한 컴포넌트
- 테마: 완전한 커스터마이징
- 접근성: WAI-ARIA 준수
- TypeScript: 완벽한 지원
2. 설치 및 설정
설치
npm install @mui/material @emotion/react @emotion/styled
아이콘
npm install @mui/icons-material
기본 사용
import { Button, Box, Typography } from '@mui/material';
export default function App() {
return (
<Box sx={{ p: 4 }}>
<Typography variant="h4" gutterBottom>
Welcome to MUI
</Typography>
<Button variant="contained">Click me</Button>
</Box>
);
}
3. 기본 컴포넌트
import {
Button,
TextField,
Checkbox,
Radio,
Select,
Switch,
Slider,
Rating,
} from '@mui/material';
export default function Components() {
return (
<>
<Button variant="contained">Contained</Button>
<Button variant="outlined">Outlined</Button>
<Button variant="text">Text</Button>
<TextField label="Email" variant="outlined" />
<TextField label="Password" type="password" />
<Checkbox defaultChecked />
<Radio />
<Switch defaultChecked />
<Slider defaultValue={50} />
<Rating defaultValue={3} />
</>
);
}
4. Layout
import { Container, Grid, Box, Stack, Paper } from '@mui/material';
export default function Layout() {
return (
<Container maxWidth="lg">
<Grid container spacing={3}>
<Grid item xs={12} md={6}>
<Paper sx={{ p: 2 }}>Card 1</Paper>
</Grid>
<Grid item xs={12} md={6}>
<Paper sx={{ p: 2 }}>Card 2</Paper>
</Grid>
</Grid>
<Stack direction="row" spacing={2} mt={4}>
<Box>Item 1</Box>
<Box>Item 2</Box>
</Stack>
</Container>
);
}
5. sx Prop
import { Box } from '@mui/material';
export default function SxProp() {
return (
<Box
sx={{
p: 4,
m: 2,
bgcolor: 'primary.main',
color: 'white',
borderRadius: 2,
'&:hover': {
bgcolor: 'primary.dark',
},
}}
>
Styled Box
</Box>
);
}
6. Theming
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#3498db',
},
secondary: {
main: '#2ecc71',
},
},
typography: {
fontFamily: 'Arial, sans-serif',
h1: {
fontSize: '2.5rem',
fontWeight: 700,
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 8,
textTransform: 'none',
},
},
},
},
});
export default function App() {
return (
<ThemeProvider theme={theme}>
{/* 컴포넌트 */}
</ThemeProvider>
);
}
7. Dark Mode
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { CssBaseline, Button } from '@mui/material';
import { useState } from 'react';
export default function App() {
const [mode, setMode] = useState<'light' | 'dark'>('light');
const theme = createTheme({
palette: {
mode,
},
});
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>
Toggle {mode === 'light' ? 'Dark' : 'Light'}
</Button>
</ThemeProvider>
);
}
8. Form 예제
import {
Box,
TextField,
Button,
FormControl,
FormLabel,
FormHelperText,
Stack,
} from '@mui/material';
import { useForm, Controller } from 'react-hook-form';
interface FormData {
email: string;
password: string;
}
export default function LoginForm() {
const { control, handleSubmit, formState: { errors } } = useForm<FormData>();
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<Box component="form" onSubmit={handleSubmit(onSubmit)} sx={{ maxWidth: 400 }}>
<Stack spacing={3}>
<Controller
name="email"
control={control}
rules={{ required: 'Email is required' }}
render={({ field }) => (
<TextField
{...field}
label="Email"
error={!!errors.email}
helperText={errors.email?.message}
/>
)}
/>
<Controller
name="password"
control={control}
rules={{ required: 'Password is required' }}
render={({ field }) => (
<TextField
{...field}
label="Password"
type="password"
error={!!errors.password}
helperText={errors.password?.message}
/>
)}
/>
<Button type="submit" variant="contained" fullWidth>
Submit
</Button>
</Stack>
</Box>
);
}
9. Icons
import { Button } from '@mui/material';
import { Send, Delete, Add } from '@mui/icons-material';
export default function Icons() {
return (
<>
<Button startIcon={<Send />}>Send</Button>
<Button startIcon={<Delete />} color="error">
Delete
</Button>
<Button startIcon={<Add />} variant="outlined">
Add
</Button>
</>
);
}
정리 및 체크리스트
핵심 요약
- MUI: React Material Design 라이브러리
- 100+ 컴포넌트: 풍부한 컴포넌트
- 테마: 완전한 커스터마이징
- 접근성: WAI-ARIA 준수
- 다크 모드: 내장
- TypeScript: 완벽한 지원
구현 체크리스트
- MUI 설치
- Provider 설정
- 기본 컴포넌트 사용
- Layout 구성
- Form 구현
- Theming 커스터마이징
- Dark Mode 구현
- Icons 활용
같이 보면 좋은 글
- Chakra UI 완벽 가이드
- shadcn/ui 완벽 가이드
- React 완벽 가이드
이 글에서 다루는 키워드
MUI, Material UI, React, Material Design, Theming, TypeScript, Frontend
자주 묻는 질문 (FAQ)
Q. Chakra UI와 비교하면 어떤가요?
A. MUI가 더 많은 컴포넌트를 제공합니다. Chakra UI가 더 간단하고 커스터마이징이 쉽습니다.
Q. 번들 크기는 어떤가요?
A. Tree-shakable이지만, 전체적으로 큰 편입니다.
Q. Material Design만 가능한가요?
A. 아니요, 테마로 완전히 커스터마이징할 수 있습니다.
Q. 프로덕션에서 사용해도 되나요?
A. 네, Google, Netflix 등 대기업에서 사용하고 있습니다.