react를 이용한 web clock만들기

javascript30의 2번째 강좌 CSS + JS를 이용한 clock구현을 react로 변경해보도록 하겠다.이번 포스팅에서는 state에 현재 시간, 분, 초를 놓고 1초마다 갱신하는 action을 dispatch시키는 방식으로 구현해볼 것이다.

초기 기본 코드는 위에 있는 github저장소에 올라와있다.

이번 작업 역시 CRA(Create React App)을 통해 환경을 구축하고 actions와 reducers를 만들고 시작할 것이다.

먼저 action에서는 시간 state를 반환해주는 setTime function을 만들었다.

// actions/index.jsexport const SET_TIME = 'SET_TIME';

export function setTime(hours, minutes, seconds) {
return {
type: SET_TIME,
hours: hours,
minutes: minutes,
seconds: seconds
}
}

시간, 문, 초를 받아서 SET_TIME타입의 새 state를 return해주었다.

// reducers/index.jsimport {SET_TIME} from "../actions";

const now = new Date();

const defaultTime = {
hours: now.getHours(),
minutes: now.getMinutes(),
seconds: now.getSeconds(),
};

function clock(state = defaultTime, action) {
switch (action.type) {
case SET_TIME:
return {
hours: action.hours,
minutes: action.minutes,
seconds: action.seconds
};
default:
return state;
}
};

export default clock;

reducer에서는 SET_TIME action이 들어올 경우 전달받은 시간으로 state를 갱신해준다. default값은 현재 시간으로 설정해주었다.

components/Clock.js

ClockContainer component안 포함 될 Clock component는 현재 시간 state를 각각의 시침, 분침, 초침이 몇 도 각도로 기울어 표현할지를 계산하고 css ‘transfrom’ style에 반영해준다. 이제 state가 갱신될 때마다 각 시, 분, 초침의 style이 수정될 것이다.

또한 componentDidMount를 통해서 component가 최초 렌더링된 이후에는 1초마다 현재 시간으로 state를 갱신시키도록 stInterval function을 실행시켜주었다(20th line). 안에 있는 setNowTime은 container component에서 전달받을 것이다.

components/Clock.css....hand {
...
transform-origin: 100%;
-webkit-transition: all 0.05s;
-moz-transition: all 0.05s;
-ms-transition: all 0.05s;
-o-transition: all 0.05s;
transition: all 0.05s;
transition-timing-function: ease-in-out;
...
}...

초기 코드파일에 있던 css코드는 Clock.css파일로 이동시켰다. 또한 몇 가지 추가된 사항이 있는데, transform style로 hand class(시, 분, 초침)들을 회전시킬 때 transform-origin설정을 해주지 않으면 각 요소의 중앙을 기준으로 회전하게 된다. 각 침들은 시계의 중앙, 즉 한 쪽 끝을 기준으로 회전해야 하기 때문에 ‘transform-origin: 100%’ 코드를 넣어주었다.

‘transition: all o.o5s’는 transition이 일어날 때 0.05초동안 동작이 연속적으로 이루어지도록 해주고, ease-in-out은 이 transition이 일어날 때 전체 시간동안 어떤 속도로 움직이는지를 설정해준다. ease-in-out은 시작과 끝은 천천히, 중간에 빠른 변화를 주는 동작이다. 자세한 정보는

해당 문서를 참조하면 된다.

containers/ClockContainer.js

ClockContainer component에서는 Clock에 시간 state를 넘겨주고 현재 시간으로 action을 만들어 dispatch시켜주는 setNowTime function을 만들어주었다. 앞서 보았듯이 Clock component에서는 이 함수를 전달받아 1초마다 한 번씩 실행시켜 줄것이다.

index.js에서는 이전 포스팅과 마찬가지로 reducer를 이용해 store를 만들어주고 Provider props에 담아 root div에 렌더링시켜주면 된다.

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

import rootReducer from './reducers';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

const store = createStore(rootReducer);

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);

완성된 모습은 다음과 같다.

web-clock

Github Source Code

woohyun