넷플릭스 처음 들어갔을 때 초기화면을 구현하는 중이다. 사실 초기 화면 구현을 다 했었는데 구현한 코드가 마음에 들지 않아 한번 갈아엎고 다시 만드는 중이다.
그리고 원래는 Mobx를 적용하려 했으나, Redux를 사용해보고 싶어 다 갈아엎은 것도 있다.
그래서 디렉토리 구조도 조금 바꾸었다.
redux를 적용하기 위해 redux, react-redux를 받았다. 그리고 store 폴더를 만들어 주었다. 원래는 action과 reducer 등을 따로 만들어주는 것으로 알고 있는데 나는 Ducks 패턴으로 리덕스를 구현하기 위해서 store에 modules라는 디렉토리를 만들어 주었다.
ducks 패턴의 경우, 한 파일에 구현할 기능과 관련된 액션타입과 액션 생성함수, 리듀서를 함께 만들어주고 모듈화 시켜준다. 그리고 이 리듀서 들을 modules의 index.ts에서 combineReducers로 루트 리듀서를 만들어주는 것이다. 이렇게 하면 어떤 한 기능에 대해서 수정사항등이 생겼을 때 여러 파일을 수정할 필요없이 한번에 수정할 수 있어 편한 것 같다.
지금까지 구현한 것을 (별로 하지도 않았지만) 정리하면 다음과 같다.
우선 react router dom를 이용해서 초기에 접속 시 나타나는 페이지 라우팅을 해주었다. 그리고 Link 컴포넌트를 이용해서 오른쪽 상단의 로그인 버튼을 클릭 시, 로그인 화면으로 전환될 수 있도록 로그인 페이지를 만들고 라우팅을 설정해주었다.
초기 화면의 경우에는 영역이 메인 이미지, 컨텐츠 설명, Q & A, 푸터로 크게 나누어져 있어서 각각 컴포넌트를 만들어서 레이아웃을 잡아주었다. components 디렉토리를 보면 각 영역에 대한 컴포넌트들을 확인할 수 있다.
가장 상단에 위치하는 영역을 initPageMain 컴포넌트로 만들고 여기부터 만들어주었는데, 우선은 unsplash에서 적절한 배경이미지를 하나 다운 받아서 scss에 background 이미지로 설정을 해주었다.
이 영역에는 크게 넷플릭스 로고(?) 와 로그인 버튼, 메인 텍스트, 이메일 input으로 이루어져 있다.
그래서 우선 main 컴포넌트안에 헤더 div를 만들어 주고 그 안에 로고와 로그인 버튼을 만들어주었다. 로그인 버튼은 위에서 말한 것 처럼 Link 컴포넌트를 이용해서 로그인 페이지로 라우팅 될 수 있도록 하였다.
그 다음에는 mainText div영역을 만들어주고 화면에 보이는 텍스트와 이메일 input을 넣어주었다. 이메일 input은 state와 input interaction이 있을 것 같아서 따로 컴포넌트로 만들어주었다. 그리고 처음에는 그냥 input 컴포넌트를 렌더링 해주었는데 redux를 적용하면서 input 컴포넌트를 담고있는 container로 바뀌었다.
input 컴포넌트 자체는 material-ui의 TextField를 활용했다. 실제 넷플릭스 동작을 비슷하게 구현하기 위해서 썼다.
'30일 무료이용' 버튼을 눌렀을 때 별 다른 이벤트는 아직 달아주지 않았다.
실제 넷플릭스 이메일 input에 메일을 입력하면 입력한 값이 이메일 폼이 아닐 경우, 정확한 이메일을 입력해달라는 helper 텍스트가 나온다. 이 부분을 구현하기 위해서는 input의 값을 state로 받아야할 것 같은데, 원래라면 클래스 컴포넌트로 만들어서 바로 state를 사용하면 쉽게 구현할 수 있겠지만 redux를 사용하기로 했기 때문에 이 기능과 관련된 액션과 리듀서를 구현해주었다.
ducks 패턴으로 구현하기 때문에 src/store/modules에 emailCheck라는 파일을 만들고 위와 같이 구현해주었다.
우선 액션 타입을 설정해주고, 액션 생성함수를 만들어 주었다. 타입스크립트도 쓰고 있는데 리듀서에서 액션의 반환 타입을 정해주어야해서 액션 생성함수 반환 타입을 정해주었다.
그리고 초기 상태와 초기 상태의 타입도 정해주고 리듀서를 만들어주었다.
리듀서는 파라미터로 초기 상태와 액션을 받는데 여기서 input으로 들어온 값이 '이메일 폼'이 맞는지 확인하기 위해서 정규식을 이용했다. match()를 이용해서 email이 정규식과 일치하는지에 따라 일치하면 errMsg가 'clear', 일치하지 않으면 '정확한 이메일을 입력하세요'를 반환하도록 하였다.
이렇게 모듈을 만들어주고, index.ts에서 import해서 루트 리듀서를 만들어주었다.
그리고 index.tsx에서 루트 리듀서를 import하고 store를 만들어 주었다.
루트 리듀서로 스토어를 만들고, Provider로 store를 props로 내려주었다. 그 다음 할 것은 아까 만들었던 input 컴포넌트를 연결해주어야한다. 그래서 컨테이너 컴포넌트를 만들고 다음과 같이 해주었다.
mapStateToProps와 mapDispatchToProps로 각각 store의 state와 액션 함수를 dispatch 해주었다. 그다음 컨테이너 컴포넌트를 만들고, input 컴포넌트를 렌더링하도록하고 store에서 props로 받은 email state와 input handle 함수를 props로 전달하였다. 그리고 connect로 연결해주었다.
이렇게 하고 handle함수를 input 컴포넌트에서 onChange에 달아주고 입력을 해보니 redux devtool에서 실시간으로 state값을 확인할 수 있었다. (신기)
이번까지 하면서 느낀점은 우선 리덕스를 처음 사용해보았는데, 구현할 기능에 비해 많은(?) 코드를 써야해서 좀 귀찮기도하고, 복잡하다는 생각이 들었지만 점점 프로젝트가 확장되면 오히려 이렇게 데이터와 상태를 관리하는게 확실히 강점이 있을 것 같다.
솔직히 아직은 리덕스가 좀 어렵고, 거기다가 타입스크립트까지 얹어쓰려니 더 복잡한 느낌이 있는 것은 사실이다. 그래도 점점 익숙해지다보면 좀 더 짜임새 있는 프로젝트를 만들 수 있지 않을까 생각이 든다.
'Project Devlog > 넷플릭스 클론' 카테고리의 다른 글
넷플릭스 클론 - 2 (0) | 2020.03.22 |
---|---|
넷플릭스 클론 - 1 (0) | 2020.03.20 |
댓글