본문 바로가기
Javascript

react 프로젝트에 redux 적용하기 #1

by 유세지 2020. 9. 16.

이번에 진행중인 토이 프로젝트에서 상태관리 라이브러리인 redux를 적용하게 되었습니다.

 

문제는 아직 한 번도 사용해본적이 없는 라이브러리이기에 실전에 앞서 redux가 어떤 방식으로 동작하는지, 어떻게 적용시키야 하는지 알아보기 위해 기존에 있던 react 프로젝트를 redux를 이용한 구조로 바꾸는 튜토리얼을 진행해보려고 합니다.

 

리팩토링 할 대상은 지난번 리액트 튜토리얼을 진행했던 무비앱.

이 리액트 프로젝트를 redux를 이용한 프로젝트로 탈바꿈 시켜보는게 오늘의 목표입니다.

 

redux 프로젝트로 리팩토링 할 레파지토리

 

막상 진행하려고 하니 정말 아무것도 모르는 제로 베이스 상태였기 때문에 유튜브에 올려져있는 벨로퍼트(김민준)님의 강좌를 참고하였습니다.

 

우선 기존 레파지토리를 남기고 새 프로젝트에서 작업을 시작하기 위해 새 저장소를 생성하겠습니다.

 

create a new repository

 

기존에 만들었던 프로젝트를 클론해서 푸시해주겠습니다. 이 커밋이 initial commit이 되겠네요.

 

 

이렇게 지난 작업 내용을 그대로 이어받은 새 저장소가 탄생했습니다. 사실 원본에서 다른곳에 푸시하면 빠르지만 굳이 저렇게 한 이유는 github에서 수정했던 readme 파일에 뭔가 문제가 생겼는지 pull을 받지 못해서 번거로운 과정을 거쳤습니다. 특별한 수정사항이 없으신 분들은 기존 저장소에서 리모트만 변경해서 푸시하셔도 됩니다.

 

새 저장소 세팅 완료

git clone 명령어를 통해 로컬에 저장소를 복사하고, 작업에 들어가겠습니다.

 

가장 먼저 해야할 일은 redux를 적용하기 적절한 구조로 만들어주는 일입니다. 파일들부터 뜯어 고치려고 하였는데... 그러려면 일단 redux의 구조부터 알아봐야 할 것 같습니다.

 

위 그림처럼 스토어는 각 컴포넌트의 상태를 저장하고, 컴포넌트들은 그 스토어를 구독하는 형태로 이루어져있습니다. 컴포넌트에서 상태 변화를 일으키는 동작을 시도하려면 액션을 참조하는 형태로 해야하고, 이 액션은 리듀서로 전달되어 의도한 로직을 실행하여 상태를 갱신하게 됩니다. 리듀서는 갱신된 상태를 스토어에 저장하고, 스토어를 구독하고 있는 컴포넌트로 갱신된 상태가 바로 전달되어 화면이 바뀌게 됩니다.

 

용어를 한 번 정리하고 넘어가면

 

- 상태 변화가 있을때 참조하는 actions

- 액션의 기능을 가지고 있는 reducer

- 뷰의 역할을 할 components

- 각 컴포넌트의 상태인 state와 이를 저장하는 store

 

위 과정에 알맞게 프로젝트 파일들을 다시 구성해보겠습니다.

 

 

 

actions

actions

 

 

먼저 src의 하위 디렉토리로 actions를 추가해주고, ActionTypes.jsindex.js 를 생성해줍니다.

 

 

ActionTypes.js 와 index.js 를 생성한 모습

 

ActionTypes.js 에는 상수 형태로 사용해야 할 액션의 이름들을 저장한 모습입니다. 우리는 영화 목록을 가져오는 동작을 액션으로 만들 예정이기에 이름은 GET_MOVIE 정도로 하겠습니다.

 

index.js 에는 ActionTypes.js 에서 선언했던 액션들을 불러와주겠습니다. 이름을 index로 해주게되면 나중에 actions 디렉토리만 불러왔을때 index 파일에 있는 내용들이 자동으로 추가된다고 합니다.

 

getMovie() 라는 이름으로 액션 생성자를 만들어줍니다. 이 액션 생성자는 객체를 리턴하고, 별다른 매개변수는 필요하지 않으니 빈칸으로 남겨두겠습니다.

 

나중에 다른 액션들이 필요할때면 이런식으로 파일을 만들어 생성해주고, index.js 에서 불러와주면 됩니다.

 

 

 

reducer

 

 

reducers

 

다음은 리듀서를 만들어보겠습니다. 아까 actions를 만들었을때처럼 reducers 디렉토리를 src 하위에 추가해줍니다.

 

movieFetch.js 와 index.js

 

stateaction을 매개 변수로 받는 movieFetch 함수를 선언하고, 우선은 state를 반환하도록 해줍니다. (이 부분은 잠시 후에 다시 다루겠습니다.) 지금은 state만 반환하게 하였지만 우리가 위에서 만들었던 GET_MOVIE 액션을 받게되면 case 문 안 쪽의 코드가 실행된다는 것만 알아두고, 우선은 넘어가겠습니다.

 

index.js 파일을 생성하고 movieFetch 파일을 불러옵니다. 이 파일의 역할은 actionsindex와 동일합니다.

 

이것으로 actionreducer의 연결 준비는 끝났습니다.

 

 

store

 

다음은 store를 추가해 줄 차례입니다. src 폴더에 있는 index.js를 열어줍니다.

 

경로를 잘 확인해야합니다. src/index.js 에 코드를 추가한 모습.

 

 

index.js 라는 이름을 가진 파일이 많아서 헷갈리기 쉽습니다. "src 디렉토리에 있는" index.js 를 열어주시고 코드를 추가해줍니다.

 

redux에서 createStore을 임포트 해주시고, react-redux에서 Provider를 임포트 해줍니다. 그리고 우리가 방금 만들었던 reducers의 reducers를 상대경로를 이용해 가져옵니다. (./ 은 파일이 위치한 현재경로입니다.)

우리가 아까 reducer를 만들때 reducer/index.js 파일을 이용해 취합했기 때문에, 별다른 표기 없이도 컴퓨터가 인덱스에 있겠거니 하고 임포트가 되었습니다. 물론 ./reducers/index.js 라고 표기하셔도 잘 됩니다.

 

임포트를 마쳤다면 상수 store를 만듭니다. 인수로는 reducers를 전달하면 되겠네요. 이것으로 스토어가 만들어졌습니다.

 

다음은 렌더 부분으로 가서 <App /> 을 <Provider>로 감싸줍니다. props로는 위에서 선언한 store를 전달해줍니다. 여기서 Provider는 일종의 컴포넌트인데요, 이 컴포넌트로 리덕스를 적용시킬 컴포넌트를 감싸주게되면 복잡한 작업들을 대신 처리해줍니다.

 

이것으로 스토어를 생성하고 Provider을 적용하는 것 까지 해보았습니다. 이제 리듀서에서 스토어에 접근할 수 있도록 연결해주면 리덕스를 사용할 수 있게 됩니다.

 

원래 계획은 이번 포스팅에서 끝내는 것 이었는데, 생각지도 못했던 문제를 발견해서 내용을 두 글로 나누어야 될 것 같습니다. 위쪽에서 reducers/movieFetch.js 파일에 state만 반환하도록 했던 것과 관련이 있는데요. 바로 우리가 해야할 작업이 비동기 작업이기 때문입니다.

 

이게 어떤 이유에서 문제가 되는지, 어떻게 해결할 수 있는지는 다음 포스팅에 마저 정리하도록 하겠습니다.

태그

,

댓글0