2018년 9월 4일
오늘 한 일:
- React: 음악 컨트롤러 만들기
내일 할 일:
- prestoMusic: VueJS를 이용해 웹 스킨 제작
- 컨트롤러
- 동적 앨범 뷰
- chrome slider component 스타일 변경
- 레이아웃: 서치바 이동, 메뉴 리스트 변경(플레이리스트, 앨범, 아티스트, 장르)
- 앨범 선택 시 레이아웃 및 애니메이션
React
음악 컨트롤러(music-player)
Tutorials
componenet based: ui는 상태를 스스로 관리하는 컴포넌트로 구성되어 있다.
jsx라는 xml-like 문법을 사용할 수 있다(선택)
- *.jsx는 babel이라는 preprocessor를 이용해서 생성할 수 있다
Preprocessor: css의 sass나 less 같은 것들
컴포넌트 상태가 업데이트 되면 스스로 재 렌더링 된다
용어
- stateful component: 상태를 가지는 컴포넌트. 상태변화때문에 새롭게 렌더링 될 컴포넌트
element와 component
- element
- 화면에 보여지는 것이 react element. react element는 object이므로 실제 DOM의 엘리먼트와는 다르다.
- react element는 immutable. 따라서 엘리먼트를 업데이트 하려면 새로운 엘리먼트를 렌더링 해야된다.
- component
- props 객체를 받아서 react element를 리턴하는 것
- js의 함수로 component를 구현할 수 있다
- 주의: props 객체는 read-only. props 객체를 변경하는 일은 없어야 된다
상태 관리와 life cycle hooks
react 엘리먼트의 state속성을 통해 엘리먼트별 local 속성을 지니게 할 수 있다. 이때 class
를 사용해야 한다. life cycle 메소드를 이용하여 엘리먼트에 timer를 설정할 수 있다. 컴포넌트의 결과물이 최초에 DOM에 렌더링된 상태를 mounting
, DOM이 제거된 상태를 unmounting
이라고 한다
- ComponentDidMount(): mounting 상태일 때 실행되는 메소드
- componentWillUnmount(): unmouting될 때 실행되는 메소드
event handling
lift state up
자신의 상태를 상위 엘리먼트에게 보내는 방법
구현
요구사항
- 재생을 누르면 음악이 재생된다
- 버튼이 정지 아이콘으로 바뀐다
- 플레이어 시간이 1초마다 증가한다
- 스크롤이 1초마다 증가한다
- 정지를 누르면 음악이 멈춘다
- 버튼이 재생 아이콘으로 바뀐다
- 플레이어 시간과 스크롤이 정지된다
- 스크롤을 드래그하여 재생 시점을 이동한다
- 재생중인 경우
- 스크롤을 잡고있는 동안은 플레이어시간/스크롤이 정지한다
- 스크롤 이동 위치에 따라 플레이어시간/스크롤이 변경된다
- 스크롤을 놓아주면 다시 재생된다
- 일시정지인 경우
- 스크롤 이동 위치에 따라 플레이어시간/스크롤이 변경된다
- 스크롤을 놓아줘도 재생되지 않는다
- 재생중인 경우
- 스크롤을 클릭하여 재생시점을 이동한다
- 재생중의 경우
- 스크롤이 클릭된 위치에 플레이어시간/스크롤이 이동한다
- 해당위치에서 재생된다
- 일시정지인 경우
- 클릭된 위치에 플레이어시간/스크롤이 이동한다
- 음악은 재생되지 않는다
- 재생중의 경우
- 재생이 완료될 경우 정지로 변경
설계
컴포넌트화
- Player(albumCoverUrl, title, singer, runningTime, core) : 최상위 컴포넌트
- CurrentSong(albumCoverUrl, title, singer)
- PlayerControls(runningTime)
- HorizontalDragBar() : volume에도 사용될 컴포넌트
- PlayerOptions()
- HorizontalDragBar
컴포넌트별 구조
HorizontalDragBar
-
드래그
-
클릭
class HorizontalDragBar extends React.Component {
constructor(props) {
this.state = {offsetX: 0};
}
clickPosition({offsetX}) {
this.setState({offsetX: offsetX})
}
render(){
return <div style= onClick={this.clickPosition.bind(this)} />;
}
}
- 외부와의 연결
class HorizontalDragBar extends React.Component {
constructor(props) {
// props.onChangePosition()
this.state = {..., location: 0} // location은 퍼센트
}
changePosition() {
this.props.onChangePosition(this.state.location) // 바인딩 된 함수에 loc값을 넣어준다
}
trigger() {
}
render() {
return <div
onDrag={this.changePosition.bind(this)}
onMouseUp = {this.trigger.bind(this)}
/> // 드래그 될 때 마다
}
}
- 가장 상위 엘리먼트(player)가 location 퍼센테이지값을 state에 저장하고 있다가 trigger가 발생되면 무언가를 실행한다