์ค๋์ ๋ฌ๋ ฅ ํ์ด์ง๋ฅผ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์ ์บก์ณํ ๊ทธ๋ฆผ์ฒ๋ผ ์ ๊ฐ ์ํ๋ ๋ฌ๋ ฅ ๋ชจ์ต์ด ๋์ค๊ธฐ๊น์ง ์ ๋ง์ ์ํ์ฐฉ์ค๊ฐ ์์๋ต๋๋ค. ์ ์๊ฒ ๊ฐ์ฅ ์ด๋ ค์ ๋ ๋ถ๋ถ์ธ๋ฐ์.
๋ฌ๋ ฅ์ด ์ ์ผ ํฐ ๋๊ด์ด๋ผ๊ณ ์๊ฐํ์๋๋ฐ.. ๊ณ์ ์ถ๊ฐ์ ์ผ๋ก ๊ธฐ๋ฅ์ ๋ง๋ค๋ฉด์ ํ์ฌ ์ง๋ฉดํ๊ฒ ๋ ๋ฌธ์ ๋ค์ด ๋ชจ๋ ์ด๋ ต๊ธด ๋ง์ฐฌ๊ฐ์ง๋ค์.
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ์ด์ง๋ง ๋ณด๋ฉด ์๋ฒฝํ๊ฒ ์์ฑ๋์ด ๋ณด์ด์ง๋ง ์์ง ํด๊ฒฐํ์ง ๋ชปํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๊ทธ ๋ถ๋ถ์ ์ถํ ํด๊ฒฐํด๋ณด๋ก ํ๊ฒ ์ต๋๋ค.
์ฐ์ ์ด๋ ๊ฒ ๋ฌ๋ ฅ ๋ง๋๋ ๊ณผ์ ์ ๋ํด ์์ธํ ์ ์ด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
โ๏ธ ๋ฌ๋ ฅ์ ๊ทธ๋ ค๋ด๋ด
โ๏ธ ๋ฐ์ดํฐ ์คํค๋ง ๋ฌธ์ ์ ๋ฐ๊ฒฌ์ผ๋ก ๋ฌ๋ ฅ์ ๋ค์ ๊ทธ๋ ค๋ด๋ด
โ๏ธ ํ ์์ผ, ์ผ์์ผ ์๊น ๊ตฌ๋ถํด์ฃผ๊ธฐ
โ๏ธ ์ค๋ ๋ ์ง ํ์ํด์ฃผ๊ธฐ
โ๏ธ ๋ณด์ฌ์ง๋ ๋ฌ๋ ฅ์์ ์ด์ ๋ฌ & ๋ค์ ๋ฌ ๋ ์ง ํ๋ฆฌ๊ฒ ํํํ๊ธฐ
๐ฒ ๋ถ๋ณ์ฑ ๊นจํธ๋ฆฌ์ง ์๊ณ ์๋ก์ด ๋ฐฐ์ด๋ก ๋ฆฌํดํ๋ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝ ํ์!
๐ฒ ์ค๋ ๋ ์ง๊ฐ ์ฃผ๋ง์ด๋ฉด ์๊น์ด ๋ณํ์ง ์๋ ๋ฌธ์ ์ ๋ฐ๊ฒฌ
๐ฒ ํ์ฌ ๋ฌ ์์์ผ์ด ์ผ์์ผ์ด๋ฉด ์ด์ ๋ฌ ๋ฐ์ดํฐ๋ ํ์ํ์ง ์์
๋ฌ๋ ฅ์ ๊ทธ๋ ค๋ด๋ ๊ฒ์ด ๋ง์ฐํ๊ธฐ์ ์ฐ์ ๊ตฌ๊ธ๋ง์ ํ์์ต๋๋ค.
"์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ฌ๋ ฅ ๋ง๋ค๊ธฐ"
์ฐธ๊ณ ๋ธ๋ก๊ทธ 2๊ฐ๋ฅผ ์ฐพ์์ ์ฐธ๊ณ ํ์ต๋๋ค.
์ฐธ๊ณ ๋ธ๋ก๊ทธ1 : https://bigtop.tistory.com/66
์ฐธ๊ณ ๋ธ๋ก๊ทธ2 : https://velog.io/@mygomi/React-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EC%97%86%EC%9D%B4-%EC%BA%98%EB%A6%B0%EB%8D%94-%EA%B5%AC%ED%98%84
๋ฌ๋ ฅ์ ์ด๋ป๊ฒ ๊ทธ๋ ค๋ผ์ง์ ๋ํด ๊ณ ๋ฏผํด๋ณด์์ต๋๋ค.
๊ณ ๋ฏผ 1๏ธโฃ
ํด๋น ์ ๋ ์ง๋ง ๊ทธ๋ ค๋ธ๋ค.
๊ณ ๋ฏผ 2๏ธโฃ
ํด๋น ์ ๋ ์ง ์ ์ด์ ๋ฌ, ๋ค์ ๋ฌ ๋ ์ง๋ฅผ ๊ทธ๋ ค๋ธ๋ค.
์ด๋ป๊ฒ CSS๋ฅผ ์ ์ฉํด์ ๋ฐ์คํ ์ด๋ธ์ ๋ง๋ค์ด ๋ผ์ง์ ๋ํ ๊ณ ๋ฏผ์ ํ์์ต๋๋ค.
์์ผ๋ก ๊ทธ๋ฆผ์ ๊ทธ๋ ค๋ณด๋ฉด 7๊ฐ์ ์นธ์์ ๊ฐ๊ฐ ์์ผ๊ณผ ๋ ์ง๋ฅผ ๊ทธ๋ ค๋ด๋ ๊ฒ์ ์ฌ์ด ์ผ์ด์ง๋ง ์ฝ๋๋ก ์ด๋ป๊ฒ ํ์ด๋ด์ผํ ์ง ๋ง์ฐํ ์ด๋ ต๊ฒ๋ง ๋๊ปด์ง๋ค์.
๊ทธ๋์ ์์ฃผ ์๊ฒ ์๊ฒ ์ชผ๊ฐ์ด ๋ณด์์ต๋๋ค.
์์ ๋ธ๋ญ์ผ๋ก ๋ง๋ค์ด ๊ทธ ๋ธ๋ญ๋ค์ ์กฐ๋ฆฝํ์ฌ ์์ฑ๋ณธ์ผ๋ก ๋ง๋ค๋ฉด ๋์ง ์์๊น ํ๋ ์๊ฐ์ ํด๋ณด์์ต๋๋ค.
(๋ฌ๋ ฅ ํ ์ด๋ธ = 7 x ( 1 + 4 ๋๋ 5 ) )
โก๏ธ (์์ผ ํ ์ด๋ธ = 7 x 1 ) + (๋ ์ง ํ ์ด๋ธ = 7 x 4 ๋๋ 5 )
โก๏ธ (์์ผ ํ ์ด๋ธ = 7 x 1 ) + {(์ฃผ ํ ์ด๋ธ = 7 x 1) x 4 ๋๋ 5 }
๊ทธ๋์ ์๋์ ๊ฐ์ด ์์ผ์ปดํฌ๋ํธ์ ๋ ์ง์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด์ ์กฐ๋ฆฝํ๋ ค๊ณ ํฉ๋๋ค.
<Calendar>
<CalendarDays />
<CalendarMonth />
</Calendar>
๊ทธ๋ฆฌ๊ณ ์ฒซ ๋ฒ์งธ ๊ณ ๋ฏผ์ ๊ฒฐ์ ์ผ๋ก "2๏ธโฃ ํด๋น ์ ๋ ์ง ์ ์ด์ ๋ฌ, ๋ค์ ๋ฌ ๋ ์ง๋ฅผ ๊ทธ๋ ค๋ธ๋ค." ๋ฅผ ์ ํํ์ต๋๋ค.
๋ ์ง๋ฅผ ๊ทธ๋ ค๋ด๋ ค๋ฉด Date ๊ฐ์ฒด๊ฐ ํ์ํฉ๋๋ค.
์ฝ๋ฉ ์
๋ฌธํ ๋ JavaScript Date ๊ฐ์ฒด ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋๋ก ์ฌ์ฉํด๋ณด์ง ๋ชปํ๋๋ฐ ์ด์ ์์ผ Date ๊ฐ์ฒด ๋ฅผ ๊ณต๋ถํด๋ณด๋ ์๊ฐ์ ๊ฐ๊ฒ ๋์๋ค์.
Date ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
์ ๊ฐ ์ ํํ ๋ฌ๋ ฅ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
1๏ธโฃ previousDates
2๏ธโฃ thisDates
3๏ธโฃ nextDates
์ด์ ๋ฌ ๋ ์ง์, ํ์ฌ ๋ฌ ๋ ์ง์ ๋ค์ ๋ฌ ๋ ์ง๋ค์ ๋ด์ ๊ทธ๋ฆ์ ๋ง๋ค์ด์ผ๊ฒ ๋ค์. ์ด ๋ฐฐ์ด๋ค์ ํฉ์ฒดํด์ฃผ๋ฉด ํ์ฌ ๋ณด์ฌ์ง๋ ๋ฌ๋ ฅ์์ ํ์ํ ๋ ์ง๋ค์ ๊ตฌํ ์ ์๊ฒ ๋ค์.
const previousDates = [];
const thisDates = [];
const nextDates = [];
๊ทธ๋ฆฌ๊ณ ๊ฐ๊ฐ ๊ทธ๋ฆ์ ๋ด์๋ด์ผ ํ date๋ค์ ๊ตฌํ๊ธฐ ์ํด์ ๊ธฐ์ค์ด ๋๋ ๋ฐ์ดํฐ๋ค์ด ํ์ํฉ๋๋ค.
๊ทธ๋์ ์ ๋ ์๋์ ๊ฐ์ด 4๊ฐ์ง ๋ณ์๋ฅผ ๋ง๋ค์ด์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ด์๋ผ ์์ ์ ๋๋ค.
1๏ธโฃ lastDateOfPreviousMonth (์ด์ ๋ฌ ๋ง์ง๋ง ๋ ์ง)
2๏ธโฃ lastDayOfPreviousMonth (์ด์ ๋ฌ ๋ง์ง๋ง ์์ผ)
3๏ธโฃ lastDateOfThisMonth (์ด๋ฒ ๋ฌ ๋ง์ง๋ง ๋ ์ง)
4๏ธโฃ lastDayOfThisMonth (์ด๋ฒ ๋ฌ ๋ง์ง๋ง ์์ผ)
์ฐธ๊ณ ๋ก ์ด๋ฒ ํ๋ก์ ํธ๋ ๋ฆฌ๋์ค ํดํท์ ์ฌ์ฉํ๋ค.
์ด์ ํธ : ๐ Mine ์ ํ๋ฆฌ์ผ์ด์ ํ๋ก์ ํธ - ์์ฐ ํ์ด์ง
์ด์ ํธ์์๋ "๋ฆฌ์กํธ, ๋ฆฌ๋์ค๋ฅผ ์ด์ฉํด์ input๊ฐ์ ๋ณ๊ฒฝํ๋ ๊ณผ์ ์๊ฐ"๋ก ๋ฆฌ์กํธ์์๋ useState๋ก ์ํ๋ฅผ ์ ์ฅํ๊ณ , ๋ฆฌ๋์ค์์๋ ์ํ ๊ด๋ฆฌ๋ฅผ ๋ฆฌ๋์์์ํ๊ณ ์ก์ ์ ๋ง๋๋ ๊ฒ์ ๋ค๋ฃจ์ด ๋ณด์์ต๋๋ค.
์ด๋ฒ ํธ์์๋ ํ๋ก์ ํธ์์ ๋ฆฌ๋์ค ํดํท์ ์ฌ์ฉํด์ ์งํํ๊ณ ์๋ ๊ณผ์ ์ ๋ค๋ฃฐ๋ ค๊ณ ํฉ๋๋ค.
๋ฆฌ๋์ค์์ ์ํ ๊ด๋ฆฌ๋ reducer.js ์ actions.js ํ์ผ์์ ๊ด๋ฆฌํ์์ต๋๋ค. ์ดํ๋ฆฌ์ผ์ด์ ์ด ๋ณต์กํด์ง์๋ก ์ก์ ๊ณผ ๋ฆฌ๋์์ ๋ํ ๊ด๋ฆฌํ ๋ณต์กํด์ง๊ฒ ์ฃ ?
slice.js ํ์ผ์์ ๋ฆฌ๋์์ ์ก์ ์ ํ๊บผ๋ฒ์ ๊ด๋ฆฌํ ์ ์๋ ๋ฆฌ๋์ค ํดํท์ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
์๋์ ๊ฐ์ด slice.js ํ์ผ์ ๋ง๋ค์์ต๋๋ค.
ํ์ํ ๋ฐ์ดํฐ์ ์ก์
์ ์ ์ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
import { createSlice } from '@reduxjs/toolkit';
const { actions, reducer } = createSlice({
name: '',
initialState: {},
reducers: {},
});
export {
actions,
reducer,
};
๋ฌ๋ ฅ์ ๊ทธ๋ฆด๋ year๊ณผ month๊ฐ ํ์ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ด๋์ ํ ๋๋ ํ์ํ ๊ฒ ๊ฐ์ต๋๋ค.
์๋์ ๊ฐ์ด ์ ์ํ๋ฉด ๋ฉ๋๋ค.
import { createSlice } from '@reduxjs/toolkit';
const { actions, reducer } = createSlice({
name: 'application',
initialState: {
year: 2021,
month: 7,
},
reducers: {},
});
export const {} = actions;
export default reducer;
์ ๋ ์ต๋ํ ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ๋ฉด์ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์ด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
import CalendarContainer from './CalendarContainer';
export default function CalendarPage() {
return (
<>
<CalendarContainer />
</>
);
}
์ปจํ
์ด๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค์์ต๋๋ค.
๋ฆฌ๋์ค(์ค์ ์ํ ์ ์ฅ์)์์ state๋ฅผ ๊บผ๋ด ์ค๊ฒ ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ CalendarMonth ์ปดํฌ๋ํธ์ props๋ก ๋๊ฒจ์ฃผ๊ฒ ์ต๋๋ค.
import { useSelector } from 'react-redux';
import CalendarDays from './CalendarDays';
import CalendarDates from './CalendarDates';
export default function Calendar() {
const { year, month } = useSelector((state) => ({
year: state.year,
month: state.month,
}));
return (
<>
<CalendarDays />
<CalendarMonth
year={year}
month={month}
/>
</>
);
}
์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
์ ๊ฐ ์๊ฐํ ๋ ์ฌ๊ธฐ์ days๋ ๋ฆฌ๋์ค์ ์ ์ฅํด์ ์ฌ์ฉํ์ง ์์๋ ๋ ๊ฒ ๊ฐ์์ useState๋ฅผ ์ฌ์ฉํ์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๊ตณ์ด useState๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์๋์ ๊ฐ์ด ํํํด์ค๋ ๋ฉ๋๋ค.
const days = ['์ผ', '์', 'ํ', '์', '๋ชฉ', '๊ธ', 'ํ '];
๊ทธ๋ฆฌ๊ณ map ํจ์๋ฅผ ์ฌ์ฉํด์ ์์ผ ํ ์ด๋ธ์ ๋ง๋ค์ด ๋ณด์์ต๋๋ค.
import React, { useState } from 'react';
export default function CalendarDays() {
const [days] = useState(['์ผ', '์', 'ํ', '์', '๋ชฉ', '๊ธ', 'ํ ']);
return (
<>
<div>
{
days.map((day) => (
<Day
key={day}
>
{day}
</Day>
))
}
</div>
</>
);
}
export default function CalendarMonth({ year, month }) {
// Date๊ฐ์ฒด๋ฅผ ํ์ฉํด์ "์ด์ ๋ฌ ๋ง์ง๋ง ๋ ์ง"์ "์ด์ ๋ฌ ๋ง์ง๋ง ์์ผ" ๊ตฌํ๊ธฐ
const lastDateOfPreviousMonth = new Date(year, month - 1, 0).getDate();
const lastDayOfPreviousMonth = new Date(year, month - 1, 0).getDay();
// Date๊ฐ์ฒด๋ฅผ ํ์ฉํด์ "์ด๋ฒ ๋ฌ ๋ง์ง๋ง ๋ ์ง"์ "์ด๋ฒ ๋ฌ ๋ง์ง๋ง ์์ผ" ๊ตฌํ๊ธฐ
const lastDateOfThisMonth = new Date(year, month, 0).getDate();
const lastDayOfThisMonth = new Date(year, month, 0).getDay();
// ์ด์ ๋ฌ ๋ ์ง, ๋ค์ ๋ฌ ๋ ์ง๋ฅผ ๊ตฌํด์ ๋ด์ ๊ทธ๋ฆ์ ์ ์ํด์ค๋ค.
// ์ด๋ฒ ๋ฌ ๋ ์ง๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
const previousDates = [];
const thisDates = [...Array(lastDateOfThisMonth + 1).keys()].slice(1);
const nextDates = [];
// previousDates๋ฅผ ์ฑ์์ค๋๋ค.
if (lastDayOfPreviousMonth !== 6) {
for (let i = 0; i < lastDayOfPreviousMonth + 1; i++) {
previousDates.unshift(lastDateOfPreviousMonth - i);
}
}
// nextDates๋ฅผ ์ฑ์์ค๋๋ค.
for (let i = 1; i < 7 - lastDayOfThisMonth; i++) {
nextDates.push(i);
}
// ๊ทธ๋ฆฌ๊ณ ์ด์ ๋ฌ, ์ด๋ฒ ๋ฌ, ๋ค์ ๋ฌ์ ํฉ์ณ์ค๋๋ค.
const dates = previousDates.concat(thisDates, nextDates);
// ๊ทธ๋ฆฌ๊ณ weeks ํ
์ด๋ธ๋ก ๊ฐ๊ฐ date๋ฅผ ๋๋์ด ๋ด์ต๋๋ค.
const weeks = [];
for (let i = 0; i <= 35; i += 7) {
weeks.push([...dates].slice(i, i + 7));
}
// ๋ง์ง๋ง์ผ๋ก map ํจ์๋ฅผ ์ฌ์ฉํด์ ํ์ํ ๋ฐ์ดํฐ๋ค์ ์ถ๋ ฅํด๋
๋๋ค.
return weeks.map((week) => (
<div
key={week}
>
{
week.map((date) => (
<div
key={date}
>
{date}
</div>
))
}
</div>
));
}
css๋ก ์ด๋ ๊ฒ ๋ฌ๋ ฅ ํ
์ด๋ธ์ ๋ง๋ค๋ฉด
์๋์ ๊ฐ์ด 2021๋
7์์ ๊ทธ๋ ค๋ด๋ณด์์ต๋๋ค.
์ถ๊ฐ ํด์ผํ ๊ธฐ๋ฅ 1. ํ ์์ผ, ์ผ์์ผ ์๊น ๊ตฌ๋ถํด์ฃผ๊ธฐ
์ถ๊ฐ ํด์ผํ ๊ธฐ๋ฅ 2. ์ค๋ ๋ ์ง ํ์ํด์ฃผ๊ธฐ
์ถ๊ฐ ํด์ผํ ๊ธฐ๋ฅ 3. ๋ณด์ฌ์ง๋ ๋ฌ๋ ฅ์์ ์ด์ ๋ฌ & ๋ค์ ๋ฌ ๋ ์ง ํ๋ฆฌ๊ฒ ํํํ๊ธฐ
์ด๋ ๊ฒ ์ถ๊ฐํด์ฃผ๋ฉด ์์ ๋ฌ๋ ฅ์ด ๊ทธ๋ ค์ง ๊ฒ ๊ฐ๋ค์:)
๋ค์ ํธ์์๋ ์ ์ด๋ํ๋ ๊ธฐ๋ฅ๊ณผ ๋ฐ์ดํฐ ์คํค๋ง ๋ฌธ์ ์ ๋ฐ๊ฒฌ์ผ๋ก ๋ฌ๋ ฅ์ ๋ค์ ๊ทธ๋ ค๋ ค๋ด๋ ๊ณผ์ ๊ณผ ์ ์ ์ผ๋ก ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋์ ์ผ๋ก ๋ณ๊ฒฝ ํ๋ ๊ฒ์ ๋ํด ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํฉ๋๋ค.