[Reactjs] 리액트 정리 2편 : redux project 소개(2)
[Reactjs] 리액트 정리 2편 : redux project 소개(2)
안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 지난시간에 이어 리액트 리덕스에 대한 정리 2편을 포스팅 하고자합니다. 필자는 지난 2년간 시스템 엔지니어로서 활동을 했었습니다. 애초에 시작을 스크립트 언어를 주로 다루다보니 자연스레 Front-end
에 관심을 많이 갖게 되었었는데, 최근들어 리액트를 활용하여 어플리케이션 개발을 진행하다 보니, 이것저것 심화해서 공부를 진행하고 있습니다.
지난 글들은 아래를 참고 해주시면 됩니다.
- 리액트 정리 1편 : redux project 소개(1)
- 리액트 정리 2편 : redux project 소개(2)
- 리액트 정리 3편 : state & props
- 리액트 정리 4편 : S3 웹호스팅
- 리액트 정리 5편 : 소스 배포 – github actions
- 리액트 정리 6편 : 람다 이미지 리사이징
- 리액트 정리 7편 : CDN 적용
- 리액트 정리 8편 : 도메인 연결
- 리액트 정리 9편 : Codepipline을 통한 배포
리덕스는 사실 단독으로 사용하는 라이브러리 입니다. 어플리케이션의 상태관리를 도와주는 도구인데요. 제가 생각하는 리덕스는 마치 어플리케이션의 상태를 DB화 시켜서 한공간에서 관리를 해주고 어플리케이션은 그 저장정보에 따라 동적으로 움직이도록 해주는 것 같습니다.
필자는 사실 어떻게 보면… react와 redux의 용어 조차 혼동하고 있었습니다. 리액트는 View에 대한 Component를 제작하여 프론트엔드를 구성할 수 있는 라이브러리이고, 리덕스는 위에서 말한대로 상태를 관리하는 라이브러리 입니다.
저를 잘 아는지는 모르지만….그래도 워니즈님이라면 충분히 잘하신다는 이말이 큰 용기가 되어 열심히 공부해보기로했다.
이두가지를 혼합해서 사용할때 하나의 어플리케이션이 컴포넌트 기반하에 생산성있게 개발을 진행할 수 있습니다.
1. 어플리케이션 개요
Wonizz Repository : React Redux 어플리케이션 개발
먼저, 리덕스를 통한 컴퍼넌트를 제작할때, 어떻게 컴포넌트를 나누고, 개발을 할지 정해야합니다. 필자 같은 경우는 다음과 같은 방식으로 컴포넌트를 나누었고 그에 맞춰서 개발을 진행했습니다.
Header/Footer 사이에 Home component를 제작했고, 그 안에는 Category와 MainView 컴포넌트를 하위로 넣었습니다. 사실 Detail Page가 따로 있기는 하지만, 마치 SPA(Single Page Application) 처럼 동작하는 어플리케이션이라 따로 Detail Page가 있는것은 아니고, 클릭시에 우측으로 노출되도록 해두었습니다.
2. 상태 관리 방법
리덕스는 state
라고 하는 객체를 갖고 있는데, 여기에다가 계속해서 어플리케이션에 관련된 모든 상태들을 담고 있는 객체형태의 오브젝트입니다. 즉, json형태로 state를 관리하고 어플리케이션에서 어떠한 동작이 발생했을 때, 이 상태를 변경하게 되면, 그 상태를 지속적으로 subscribe
하고있는 컴포넌트들이 자신의 어플리케이션에 상태를 반영함으로써 UI가 변경되는 원리입니다.
필자는 위에서 이야기했듯이 이 state라는 오브젝트가 마치 DB 처럼 사용되어 데이터를 바꾸게 되면 바뀐대로 반영이 되는 것으로 생각하고 있습니다.
그림에 설명이 없으니, 다음의 블로그를 참고 부탁드립니다.
1 – 3 . 사용자 액션이 발생을 하게 되면, 해당 액션에 대한 액션 정의서를 작성하여 리듀서로 보냅니다.
4 – 6. 리듀서는 액션의 내용을 파악하고 기존의 상태를 복사한다음에 요청온 액션의 내용을 상태에 반영하여 최종적인 상태를 스토어쪽으로 보냅니다.
7 – 9. connect되어있는 컨테이너 컴포넌트(위의 예시에서는 Home)가, 하위의 View 컨포넌트(Category, MainView)에게 상태가 변경되었다고 알리고, 반영을 합니다.
3. 샘플 코드
페이지가 최초에 로드가 될떄, 데이터를 불러오 이 데이터를 state에 반영하고 컴포넌트에서 해당 상태로 변경을 하는 예시를 코드로 정리해보겠습니다.
src > index.js
ReactDOM.render((
), document.getElementById('root'));
제일 기초가 되는 index.js에서 Route 설정을 해둔 상태입니다. 보시면 /
로 접속을 하게 될 때, App + Home 컴포넌트가 호출이 됩니다.
App 같은 경우는 공통적으로 가져가는 Home + Footer 컴포넌트가 불려지는 컴포넌트입니다.
Home 컴포넌트에서는 위에 이야기한대로 Category + MainView가 호출이 되는데, 여기서 주용한것은 리스팅이 노출되는 MainView Component입니다.
src > components > Home > index.js
//컴포넌트가 실제 마운트 되고 나면, 리스팅할 데이터를 불러 옵니다.
componentWillMount() {
const tab = this.props.token ? 'feed' : 'all';
const articlesPromise = this.props.token ?
agent.Articles.feed :
agent.Articles.all;
this.props.onLoad(tab, articlesPromise, Promise.all([articlesPromise()]));
}
//onLoad 함수가 불려지면, 상태를 변경하기위해 reducer로 dispatch 합니다.
const mapDispatchToProps = dispatch => ({
onLoad: (tab, pager, payload) =>
dispatch({ type: HOME_PAGE_LOADED, tab, pager, payload }),
});
그러면, HOME_PAGE_LOADED
라는 액션 타입으로 호출이 되고, reducer에서는 여기에 매칭이 되는 상태 변경 영역으로 가서 변경작업을 수행합니다.
src > reducers > articleList.js
//리듀서는 보통 case문으로 매칭이 되는 액션타입에서 상태변경을 수행하도록 코드를 작성합니다.
//onLoad시에 request를 통해 가져온 데이터를 articles 객체에 담고 있습니다.
case HOME_PAGE_LOADED:
return {
...state,
pager: action.pager,
detail: '',
articles: action.payload[0] ? action.payload[0].hits.hits : action.payload.hits.hits,
currentPage: 0,
tab: action.tab,
size: 10,
from: 0,
};
이러한 상태는 모두 리덕스에서는 mapStateToProps
에 의해서 props로 변경이 되고, 컴포넌트에서는 이 props를 통해 접근이 가능합니다.
src > components > Home > MainView.js
//props에는 위에서 상태 변경한 articles가 담겨있기 때문에, article를 가져와서 map을 통해 리스팅을 그려줍니다.
props.articles.map((article, index) => {
const handleClick = ev => {
ev.preventDefault();
props.onClickDetail(agent.Articles.byTitle(article._source.product_title));
};
return (
);
})
이렇게 해서 MainView에 데이터를 가져와 리스팅을 했습니다.
4. 마치며..
리액트 + 리덕스를 처음 사용할때는 도저히 무슨 이야기인지, 데이터 흐름은 어떻게 되는지 이걸통해 개발을 어떻게 하는지 막막하기만 했습니다. Jquery에 너무 익숙해져있었고, DOM을 직접 제어 하다보니 컴포넌트에 대한 이해도 없었습니다. 즉각적으로 보이는데만 수정하고 하다보니 브라우저에서 css 리스케치를 할때도 비효율적이란 것을 몰랐습니다.
왜 Front-end가 React 혹은 View로 넘어가는지는 아주 조금 이해가 된 것 같습니다. 컴포넌트 기반으로 어플리케이션을 작성하다보니, 필요한 부분만 상태변경을 하고 바로바로 바꿔서 보여주다보니 브라우징 속도도 굉장히 빠른것 같습니다.
더군다나, 개발 속도가 붙기 시작했습니다. 데이터 흐름이 어떻게 되는지 이해를 하다보니 다음에는 어떻게 개발을 해야되고 어떤식으로 수정을 해야되는지 감이 잡히기 시작했습니다.
아직은 허접하기 그지 없지만, 조금씩 익숙해지면서 마치 레고를 조립하듯 개발을 하다보니 뿌듯합니다. 다음이시간에는 리액트에서 사용한 라이브러리들을 정리해보겠습니다.