Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- db
- Cloud
- github
- url
- Boostrap
- API
- SQL
- 배포
- data
- this
- HTML
- IntersectionObserver
- Fetch
- Database
- til
- Github Pages
- W
- Protocol
- http
- web
- firestoredatabase
- CSS
- bootstrap
- supabase
- jQuery
- useEffect
- nosql
- TMDB
- JavaScript
- REACT
Archives
- Today
- Total
072DATA
📅 아주아주 간단한 달력 구현 본문
오늘은 달력을 구현했는데 useCalendar라는 훅을 만들어서
달력에 관련된 로직을 관리하여 꽤 깔끔하게 설계가 된듯하다
아직까지는 이벤트 관련 로직이 없어서 UI 정도만 설계했다
다음 업데이트 해야할 사항으로 각 날짜별로 통계를 내려주고 해당 월의 통합 데이터까지 출력해야 한다
🛠️ 전체 구조 및 기술 스택
- React와 TypeScript를 사용한 달력 구현
- dayjs 라이브러리로 날짜 처리
- Custom Hook을 통한 로직 관리
- Tailwind CSS로 스타일링
💡 주요 로직 분석
1. Custom Hook (useCalendar)
상태 관리
const [currentMonth, setCurrentMonth] = useState(dayjs());
- 현재 표시되는 월을 상태로 관리
- dayjs 인스턴스를 초기값으로 설정
dayjs는 JavaScript 기반의 경량 날짜/시간 라이브러리로,
Moment.js의 현대적 대안이며 체이닝 API와 간단한 날짜 조작 기능을 제공한다고 함
날짜 데이터 생성 로직
const getDatesInMonth = (monthOffset: number): CalendarData => {
const targetMonth = currentMonth.add(monthOffset, "month");
const startOfCalendar = targetMonth.startOf("month").startOf("week");
const endOfCalendar = targetMonth.endOf("month").endOf("week");
// ...
}
targetMonth로 보여줄 월을 결정한 뒤,
startOfCalendar는 해당 월의 첫째 주 일요일을,
endOfCalendar는 마지막 주 토요일을 찾음
이렇게 하면 달력 그리드에 깔끔하게 표시할 수 있는 전체 날짜 범위가 나옴
날짜 배열 생성
const dates: DateInfo[] = [];
let day = startOfCalendar;
while (day.isBefore(endOfCalendar) || dates.length % 7 !== 0) {
dates.push({
isInCurrentMonth: day.month() === targetMonth.month(),
day
});
day = day.add(1, "day");
}
while 루프로 시작일부터 종료일까지 순회하고
각 날짜마다 현재 월 포함 여부 체크
7의 배수로 맞추어 달력 완성함
🔄 상태 변경 함수
const handleMonthChange = (offset: number) => {
setCurrentMonth(currentMonth.add(offset, "month"));
};
const handleYearChange = (offset: number) => {
setCurrentMonth(currentMonth.add(offset, "year"));
};
- 월 단위 이동과 년 단위 이동 기능 구현
- offset 값으로 이동 방향과 크기 결정
2. Calendar 컴포넌트 구현]
const { currentMonth, getDatesInMonth, handleMonthChange } = useCalendar();
const { weeks } = getDatesInMonth(0);
- useCalendar 훅에서 필요한 기능들 가져오기
- 현재 월의 주 단위 데이터 계산 -> UI 때문에 주 단위의 데이터가 필요했음
렌더링 구조
- 헤더 영역
- 연/월 표시
- 이전/다음 월 이동 버튼
- 캘린더 그리드
- 요일 헤더
- 주 단위로 날짜 표시
- 각 날짜 셀에 추가 정보 표시
이런 느낌으로 렌더링 구조를 잡으면 됨 ( 캘린더 구조만 알면 될듯 )
🎨 스타일링 특징
<div className="grid grid-cols-7 bg-gray-200 border-2 border-gray-300">
{week.map(({ day, isInCurrentMonth }) => (
<div className={`
flex flex-col items-center p-4
${!isInCurrentMonth ? "text-gray-300" : ""}
hover:bg-gray-300 transition-colors
`}>
- Tailwind CSS 활용
- Grid 시스템으로 7칸 구성
- 현재 월 여부에 따른 스타일 차이
- 호버 효과 적용
⚙️ 성능 고려사항
- 날짜 계산 최적화
- 불필요한 재계산 방지
- 캐싱 전략 검토 필요
- 렌더링 최적화
- 컴포넌트 분리 고려
- 메모이제이션 적용 검토
'FrontEnd > React' 카테고리의 다른 글
React의 성능 최적화 Hook -> useMemo & useCallback ( 깨알 감자 디바운스 ) (0) | 2024.11.07 |
---|---|
리액트 상태 관리 라이브러리 비교 Context API, Redux, Zustand (1) | 2024.09.19 |
Suspense와 ErrorBoundary를 사용하여 간단히 로딩 및 에러 처리하기 (5) | 2024.09.18 |
zustand, 스토리지 활용하기 (세션, 로컬, persist) (0) | 2024.09.16 |
`React` 북마크 기능 구현하기 + 낙관적 업데이트 (5) | 2024.09.15 |