import isAfter from 'date-fns/isAfter';
isAfter(new Date(), new Date(DATE))
날짜 비교 할 일이 있어서 별 생각 없이 new Date
를 때렸는데 safari에서 안되는 문제가 발견되었다. 콘솔을 확인해보니 yyyy-MM-dd HH:mm:ss 해당 형태의 포멧 에서는 안된다. 평소에 new Date
보다는 moment나 date-fns같은 라이브러리를 당연하게 써오다 보니 몰랐다. 그런데 또 다른 생각을 해보자면 저런 문제가 있기 때문에 더 적극적으로 라이브러리를 사용해야 한다는 게 함정.
import isAfter from 'date-fns/isAfter';
import format from 'date-fns/format';
isAfter(new Date(), format(DATE))
- 컴포넌트1
- calendar
- date-picker
- GitHub - gpbl/react-day-picker: React DayPicker is a customizable date picker component for React, with native TypeScript support.
- GitHub - deseretdigital/dayzed: Primitives to build simple, flexible, WAI-ARIA compliant React date-picker components.
- GitHub - Hacker0x01/react-datepicker: A simple and reusable datepicker component for React
- headless
- 그외
Footnotes
import {
addDays,
addMonths,
eachDayOfInterval,
eachWeekOfInterval,
startOfMonth,
} from 'date-fns'
const startOfMonthDate = startOfMonth(new Date())
const matrix = eachWeekOfInterval({
start: startOfMonthDate,
end: addMonths(startOfMonthDate, 1),
}).map((weekDay) => {
const startDate = new Date(weekDay)
return eachDayOfInterval({
start: startDate,
end: addDays(startDate, 6),
})
})
Never Call
new Date()
Inside Your Components never-call-new-date-inside-your-components
function Today({ date = formatDate(new Date()) }) {
return <label>{date}</label>
}
컴포넌트 내에서 new Date()
와 같은 비순수한 함수를 호출하면, 호출할 때마다 결과가 달라집니다. 이는 테스트에서 일관된 결과를 기대할 수 없게 만들어, 테스트가 불안정해질 수 있습니다. 코드 변경 없이도 테스트가 때로는 통과하고, 때로는 실패하는 Flaky Test를 유발할 수 있습니다.
순수하지 않은 함수의 결과나 함수를 prop
으로 전달함으로써 컴포넌트가 더 예측 가능해지고, 테스트하기 쉬워집니다. 이렇게 하면 테스트 시 특정 날짜를 제어할 수 있어, 일관적이고 신뢰할 수 있는 테스트 결과를 얻을 수 있습니다.
기본 매개변수를 사용하면 개발자 경험이 향상됩니다. 기본 동작(new Date()
로 오늘 날짜를 얻는 것)을 유지하면서도, 테스트 중 특정 값을 제공할 수 있는 유연성을 유지할 수 있습니다.
vitest와 jest에서 가짜 타이머를 사용하는 방법. 내부적으로는 @sinonjs/fake-timers를 사용. vitest와 jest 모두 시스템 시간을 조작할 수 있도록 하여 테스트가 일관되게 실행되도록 하고 다양한 시간과 날짜를 시뮬레이션하여 다양한 조건에서 코드가 예상대로 작동하는지 확인할 수 있음.
describe('isSameDate', () => {
beforeEach(() => {
vi.useFakeTimers()
vi.setSystemTime('2024-07-20')
})
afterEach(() => {
vi.useRealTimers()
})
it('현재 날짜와 동일한 날짜를 전달하면 true를 반환한다', () => {
expect(isSameDate('2024-07-20')).toBe(true)
})
it('현재 날짜와 다른 날짜를 전달하면 false를 반환한다', () => {
expect(isSameDate('2024-07-19')).toBe(false)
expect(isSameDate('2024-07-21')).toBe(false)
})
})