반응형
* 본 포스팅은 직접 구현한 코드입니다.
* 불펌 금지합니다.
* 더 좋은 코드가 있으면 가르쳐주세요 감사합니다 :)
포스팅 요약
1. 결과화면 (사진 및 동영상)
1) 사진
2) 동영상
2. 파일 구조
3. 코드
경로: public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>달력</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
경로: src/App.js
import Calendar from "./component/Calendar";
function App() {
return (
<div>
<Calendar />
</div>
);
}
export default App;
경로: src/component/Calendar.js
import React, { useCallback, useState } from "react";
import classNames from "classnames/bind";
import style from "../style/calendar.css";
const cx = classNames.bind(style);
const Calendar = () => {
const today = {
year: new Date().getFullYear(), //오늘 연도
month: new Date().getMonth() + 1, //오늘 월
date: new Date().getDate(), //오늘 날짜
day: new Date().getDay(), //오늘 요일
};
const week = ["일", "월", "화", "수", "목", "금", "토"]; //일주일
const [selectedYear, setSelectedYear] = useState(today.year); //현재 선택된 연도
const [selectedMonth, setSelectedMonth] = useState(today.month); //현재 선택된 달
const dateTotalCount = new Date(selectedYear, selectedMonth, 0).getDate(); //선택된 연도, 달의 마지막 날짜
const prevMonth = useCallback(() => {
//이전 달 보기 보튼
if (selectedMonth === 1) {
setSelectedMonth(12);
setSelectedYear(selectedYear - 1);
} else {
setSelectedMonth(selectedMonth - 1);
}
}, [selectedMonth]);
const nextMonth = useCallback(() => {
//다음 달 보기 버튼
if (selectedMonth === 12) {
setSelectedMonth(1);
setSelectedYear(selectedYear + 1);
} else {
setSelectedMonth(selectedMonth + 1);
}
}, [selectedMonth]);
const monthControl = useCallback(() => {
//달 선택박스에서 고르기
let monthArr = [];
for (let i = 0; i < 12; i++) {
monthArr.push(
<option key={i + 1} value={i + 1}>
{i + 1}월
</option>
);
}
return (
<select
onChange={changeSelectMonth}
value={selectedMonth}
>
{monthArr}
</select>
);
}, [selectedMonth]);
const yearControl = useCallback(() => {
//연도 선택박스에서 고르기
let yearArr = [];
const startYear = today.year - 10; //현재 년도부터 10년전 까지만
const endYear = today.year + 10; //현재 년도부터 10년후 까지만
for (let i = startYear; i < endYear + 1; i++) {
yearArr.push(
<option key={i} value={i}>
{i}년
</option>
);
}
return (
<select
// className="yearSelect"
onChange={changeSelectYear}
value={selectedYear}
>
{yearArr}
</select>
);
}, [selectedYear]);
const changeSelectMonth = (e) => {
setSelectedMonth(Number(e.target.value));
};
const changeSelectYear = (e) => {
setSelectedYear(Number(e.target.value));
};
const returnWeek = useCallback(() => {
//요일 반환 함수
let weekArr = [];
week.forEach((v) => {
weekArr.push(
<div
key={v}
className={cx(
{ weekday: true },
{ sunday: v === "일" },
{ saturday: v === "토" }
)}
>
{v}
</div>
);
});
return weekArr;
}, []);
const returnDay = useCallback(() => {
//선택된 달의 날짜들 반환 함수
let dayArr = [];
for (const nowDay of week) {
const day = new Date(selectedYear, selectedMonth - 1, 1).getDay();
if (week[day] === nowDay) {
for (let i = 0; i < dateTotalCount; i++) {
dayArr.push(
<div
key={i + 1}
className={cx(
{
//오늘 날짜일 때 표시할 스타일 클라스네임
today:
today.year === selectedYear &&
today.month === selectedMonth &&
today.date === i + 1,
},
{ weekday: true }, //전체 날짜 스타일
{
//전체 일요일 스타일
sunday:
new Date(
selectedYear,
selectedMonth - 1,
i + 1
).getDay() === 0,
},
{
//전체 토요일 스타일
saturday:
new Date(
selectedYear,
selectedMonth - 1,
i + 1
).getDay() === 6,
}
)}
>
{i + 1}
</div>
);
}
} else {
dayArr.push(<div className="weekday"></div>);
}
}
return dayArr;
}, [selectedYear, selectedMonth, dateTotalCount]);
return (
<div className="container">
<div className="title">
<h3>
{yearControl()}년 {monthControl()}월
</h3>
<div className="pagination">
<button onClick={prevMonth}>◀︎</button>
<button onClick={nextMonth}>▶︎</button>
</div>
</div>
<div className="week">{returnWeek()}</div>
<div className="date">{returnDay()}</div>
</div>
);
};
export default Calendar;
경로: src/style/calendar.css
button {
cursor: pointer;
}
.container {
width: 500px;
height: 400px;
margin: auto;
padding: 20px 20px;
border: 1px solid rgba(128, 128, 128, 0.267);
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.container .title {
display: flex;
}
.container .title > button {
border: none;
margin-left: 5px;
height: 20px;
align-self: center;
background: none;
}
.container .title .pagination {
margin-left: auto;
align-self: center;
}
.container .title .pagination button {
margin: 0 10px;
border: none;
background: none;
}
.container .week {
display: flex;
}
.container .week .weekday {
width: calc(500px / 7);
text-align: center;
}
.container .week .sunday {
color: red;
}
.container .week .saturday {
color: blue;
}
.container .date {
margin-top: 20px;
}
.container .date .weekday {
width: calc(500px / 7);
float: left;
text-align: center;
height: 50px;
line-height: 50px;
}
.container .date .sunday {
color: red;
}
.container .date .saturday {
color: blue;
}
.container .date .today {
background-color: rgb(88, 111, 187);
color: white;
font-weight: 700;
border-radius: 50%;
}
경로: ./package.json
{
"name": "calendar",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^13.5.0",
"classnames": "^2.3.1",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
4. 깃허브 코드 주소
https://github.com/6810779s/calendar
반응형
'웹 > (React)리액트' 카테고리의 다른 글
(React with Typescript) module not found 'sass' 에러 해결, scss 사용법 (0) | 2022.10.27 |
---|---|
(React) 리액트 커스텀 훅 custom hook 사용법+input 초기화 까지 - input (0) | 2022.09.24 |
(React) 리액트 설치 및 실행법 상세하게 이미지로 설명 [2022.05.05 기준] (1) | 2022.05.05 |
(React) 리액트 라우터 사용하여 고정 메뉴 만들기(react-router v6 2022.4 기준 최신버전) (0) | 2022.04.03 |
(React-Redux) 리액트 리덕스를 이용한 간단한 프로젝트 및 설명 (0) | 2021.09.14 |
댓글