Moment.js는 현재 유지 관리 모드에 있는 레거시 프로젝트입니다. 다른 라이브러리를 사용하시는 것을 추천드립니다. (참고)
다른 대안 라이브러리 (2023.02.25 수정)
✔ moment.js
- moment.js는 시간이 포함된 데이터를 받아 조작해야 할 경우 가장 많이 사용되는 편리한 라이브러리입니다.
- 스터디를 모집하는 사이드 프로젝트를 만들 때 사용하였습니다. 현재 시간에 따라서 스터디 신청 마감, 신청중인지 에 따라 실시간으로 변경이 되게 많드는 것이 목표였기 때문에 moment.js를 사용하였습니다.
- moment.js는 워낙 많이 사용되기 때문에 공식 문서 뿐만 아니라 잘 설명된 블로그들이 많이 존재하기 때문에 moment.js를 사용하는 자세한 방법은 생략하겠습니다.
🔸 moment 라이브러리 설치
$ npm i moment
// 또는
$ yarn add moment
🔸 moment 선언
import moment from 'moment';
// 안써도 자동으로 한국 시간을 불러온다. 명확하게 하기 위해 import
import 'moment/locale/ko';
🔸 현재 시간 가져오기
// format에 맞게 출력된다.
const nowTime = moment().format('YYYY-MM-DD HH:mm:ss');
console.log(nowTime);
// 출력 결과: 2020-08-23 12:54:30
- 하지만 현재 상황에서는 현재 상태에서는 현재 시간은 가져오지만,
F5
키를 눌렀을 때만 시간이 변경됩니다.
✌ 리액트 훅스 컴포넌트에서 setInterval 사용 시의 문제점
- 실시간으로 시간을 변경하기 위해 흔히 사용하는 setInterval을 사용해야 됩니다. 하지만 react Hooks에서 setInterval을 사용했을 때 예상대로 작동하지 않는 문제가 발생합니다.
- 이 문제에 대한 설명과 그에 대한 해결방법이 자세하게 설명되어 있는 블로그를 참고하시기 바랍니다.
- 이러한 이유와 성능상의 이슈 때문에 커스텀 Hook을 생성해서
setInterval
을 사용할 수 있습니다.
// useInterval.js 작성
import { useRef, useEffect } from "react";
export default function useInterval(callback, delay) {
const savedCallback = useRef();
useEffect(() => {
// useEffect에 매개변수로 받은 콜백을 현재 Ref로 선언해준다.
savedCallback.current = callback;
});
useEffect(() => {
function tick() {
savedCallback.current();
}
// useEffect에 Ref의 current를 setInterval를 delay 시간동안 해준다.
let id = setInterval(tick, delay);
// 언마운트되기전 clearInterval을 해준다.
return () => clearInterval(id);
}, [delay]);
}
import * as React from 'react';
import {useInterval} from 'react-use';
const Demo = () => {
const [count, setCount] = React.useState(0);
const [delay, setDelay] = React.useState(1000);
const [isRunning, toggleIsRunning] = useBoolean(true);
useInterval(
() => {
setCount(count + 1);
},
isRunning ? delay : null
);
return (
<div>
<div>
delay: <input value={delay} onChange={event => setDelay(Number(event.target.value))} />
</div>
<h1>count: {count}</h1>
<div>
<button onClick={toggleIsRunning}>{isRunning ? 'stop' : 'start'}</button>
</div>
</div>
);
};
🔸 useInterval를 사용하여 실시간 시간 사용하기
import React,{useState} from 'react';
import moment from 'moment';
import 'moment/locale/ko';
import { useInterval } from 'react-use';
const LiveTimeContainer = () => {
const [realTime, setRealTime] = useState(Date.now());
// useInterval
useInterval(() => {
setRealTime(Date.now());
}, 1000);
return <div>{seconds}</div>
}
- 위와 같이 작성하면 실시간으로
moment()
시간을 받아와 별다른 작업없이 시간이 실시간으로 1초마다 변하는 것을 확인할 수 있습니다.
✔ react-moment
- react-moment는 react에서 moment를 편리하게 사용할 수 있게 만들어 놓은 라이브러리입니다.
- 심지어 react-moment는 별다른 작업을 하지않아도 실시간으로 시간이 변하게 제공을 해줍니다.
- 📌 react-moment의 자세한 설명은 공식 문서를 참고해주세요.
🔸 react-moment 라이브러리 설치
- react-moment는 moment가 dependency되어 있기 때문에
moment
부터 설치해주어야 합니다.
$ npm i moment react-moment
// yarn
$ yarn add moment react-moment
// moment-timezone을 사용할려면
$ npm i moment-timezone
- 아래 사진은 사이드 프로젝트를 만들 때 세로고침을 하지 않아도 자동으로 시간이 변하여 접수가 열리고 접수중으로 상태가 변하고 대회도 마찬가지로 접수가 마감되고 대회시작의 상태를 알려주도록 구현하기 위해서 react-moment를 사용하였습니다.
🔸 react-moment 선언하고 기본 익히기
import React from 'react';
import Moment from 'react-moment';
const MomentDateChage = () => {
const nowTime = Date.now();
// Sun Aug 23 2020 15:43:49 GMT+0900
return <Moment>{nowTime}</Moment>;
}
- 기본적으로 react-moment는 60초(60000 milliseconds)로
interval
을 합니다. 하지만 interval
을 수정하여 사용할 수 있고 굳이 필요없는 곳에는 interval
을 disable
시킬 수 있습니다.
import React from 'react';
import Moment from 'react-moment';
const MomentDateChage = () => {
const nowTime = Date.now();
// interval 30초
//return <Moment interval = { 30000 }>{nowTime}</Moment>;
// interval disable
return <Moment interval = { 0 }>{nowTime}</Moment>;
}
- 현재 날짜에서 주어진 시간에 얼마나 지나거나 얼마나 남았는지를 알려줍니다.
- 이렇게 적용해주면 5분 후 또는 몇초 후, 몇일 후로 나오게 되는데 만약 영어로 나올 경우는 아래와 같이 적용해줍니다.
import React from 'react';
import Moment from 'react-moment';
import 'moment/locale/ko';
const MomentDateChage = () => {
const nowTime = Date.now(),
startTime = new Date("2020-08-23T16:00");
return <Moment fromNow>{startTime}</Moment>;
}
- 더 많은 기능들은 공식문서를 참고하거나 블로그를 참고하시기 바랍니다.
✌ react-moment와 moment를 사용하여 응용해보기
- 마지막으로 몇분 후 접수 시작이라고 나온뒤 접수 신청 시간이 되면 새로고침 없이 접수중으로 변경해보겠습니다.
moment
와 useInterval
를 사용하여 현재 시간을 불러오고, react-moment로 자동으로 시간이 변경되게 사용합니다.
import React,{useState} from 'react';
import moment from 'moment';
import Moment from 'react-moment';
import 'moment/locale/ko';
import { useInterval } from 'react-use';
const LiveTimeContainer = () => {
const [seconds, setSeconds] = useState(Date.now());
// useInterval
useInterval(() => {
setSeconds(Date.now());
}, 1000);
const startTime = new Date('2020-08-23T16:09'),
nowTimeFormat = new Date(seconds);
return (
<>
{startTime - nowTimeFormat > 0 ?
(<><Moment fromNow>{startTime}</Moment> 접수 시작</>) : (<div>{'접수 중'}</div>)
}
</>
)
}
📌 스터디 모집 사이트 소스를 확인해보고 싶으면 Github를 확인하시기 바랍니다.
StudyGroupsContainer.jsx
DateTimeChange.jsx
IntroduceForm.jsx
😃 또한, 수정해야할 정보나 부분이 있으면 댓글로 피드백 부탁드립니다. 🙏