React, Redux를 이용한 drum-kit만들기
Web Bos에서 제공하는 Javascript 30일 코스를 React, Redux를 사용하도록 바꾸어보도록 하겠다. 화면에는 9개의 버튼이 주어지고, 버튼 하나하나를 누를 때마다 버튼에 하이라이팅 표시가 되고 오디오가 나온다.
먼저 빠른 개발환경 구축을 위해 CRA(Create-React-App)을 사용하여 초기 환경을 세팅했다. CRA는 명령어 한 줄로 react 개발환경을 구축해준다.
$ create-react-app day1-drum_kit
설치가 완료되면
$ npm start
명령어를 통해 dev-server를 실행시킬 수 있다. 코드를 수정하면 자동으로 수정사항이 반영되니 편리하게 개발을 진행할 수 있다.
// actions/index.jsexport const PLAY = 'PLAY';
export const OFF = 'OFF';
export function play(key) {
return {type: PLAY, key}
}
export function off(key) {
return {type: OFF, key}
}
먼저 action은 두 가지를 정의했다. 하나는 버튼을 클릭하거나 키보드를 누를 때 발생하는 play action이고, 또 하나는 transition으로 버튼이 활성화 된 이후 버튼을 다시 꺼주는 off action이다.
Presentational component는 각각의 버튼을 표현하는 Key component와 audio tag인 Audio component, 이 둘을 감싸주는 KeyList component이렇게 3가지로 구성되어있다.
// components/Key.jsimport React from 'react';
const Key = ({dataKey, kbd, text, playing, onClick}) => {
const isPlaying = playing ? 'playing' : '';
return (
<div data-key={dataKey} className={`key ${isPlaying}`} onClick={() => {onClick(dataKey)}}>
<kbd>{kbd}</kbd>
<span className="sound">{text}</span>
</div>
)
};
export default Key;
Key component는 해당 키의 keyCode값인 dataKey와 단축키 kbd, audio를 설명해주는 text
- dataKey는 해당 키의 keyCode값이다. 일종의 id역할을 하게 된다.
- kbd는 단축키 문자를 의미한다.
- text는 사용자에게 이 버튼이 어떤 소리를 내는지를 표시해준다.
- playing은 버튼이 활성화되었을 때 true값으로 변경된다. playing state가 true가 되면 해당 버튼의 class에 ‘playing’이 추가된다.
- onClick은 해당 버튼이 클릭될 경우 action을 만들어 dispatch시킨다.
// components/Audio.jsimport React from 'react';
const Audio = ({dataKey, text}) => {
return (
<audio data-key={dataKey} src={`sounds/${text}.wav`} />
)
};
export default Audio;
Audio는 dataKey와 text를 받아 Audio태그를 만들어준다.
KeyList.js에서는 뒤에 설명 할 KeyListContainer에서 keys를 전달받아 Key components와 Audio components를 만들어준다. componentDidMount는 react에서 초기에 Component가 만들어지면 한 번 실행되는 function으로서,
- 각 버튼의 transitioned event가 발생하면(transition이 끝나고 나면) removeTransition function을 실행시키는 기능과
- 키보드가 눌렸을 때 onKeyDown function을 실행시키는
두 가지 기능을 수행한다.
유일한 container component인 KeyListContainer는mapStateToProps function을 통해 key들의 상태를 관리하는 keys를 KeyList component에 전달해준다.
action을 만들어 dispatch시켜주는 mapDispatchProps는 3가지, onKeyDown과 onClick의 경우 audio를 실행시키고 해당 키의 play action을 발생시키며, removeTransition은 off action을 발생시킨다.
Reducer에서는 PLAY type action이 들어오면 해당 key의 playing을 true로 변경해주고, OFF type action이 들어오면 해당 key의 playing을 false로 변경해준다. 초기에 기본적으로 생성해줄 keys역시 여기서 초기화시켜주었다.
마지막으로 App.js에서 KeyListContainer를 생성해주고
// App.jsimport React, { Component } from 'react';
import './App.css';
import KeyListContainer from './containers/KeyListContainer';
class App extends Component {
render() {
return (
<div className="App">
<KeyListContainer />
</div>
);
}
}
export default App;
index.js에서 store를 생성해 root div에 App component를 렌더링해주면
// index.jsimport 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')
);
성공적으로 동작하는 것을 볼 수 있다!