이번 포스팅에서는 React, TypeScript. Redux, Redux-Saga를 통해서 간단한 뉴스 어플리케이션을 만들어 보려고 한다.
React는 사용자 인터페이스를 만들기 위한 자바스크립트 라이브러리이다. 현재 전 세계에서 가장 많이쓰이고 있는 웹 프론트엔드 라이브러리이다. 어플리케이션의 뷰(View) 부분에 특화되어 상태에 해당되는 데이터들만 빠르게 주고받으며 우수한 성능을 가지는 어플리케이션을 만들 수 있다는 장점이 있다.
TypeScript는 자바스크립트의 상위 호환 언어로 정적 타입을 지원하며, 객체지향 프로그래밍을 하기 위한 문법을 제공하는 언어이다. 안정성이 높으면서 성능 면에서도 자바스크립트에 비해 크게 뒤떨어지지 않기 때문에 많은 회사들은 점점 타입스크립트를 도입하고 있는 추세이다.
Redux는 컴포넌트 간에 데이터를 쉽고 효율적으로 주고 받을 수 있도록 설계된 라이브러리이다. 코드의 유지 보수성을 높여주고 작업 효율을 극대화 한다는 장점이 있으며, 미들웨어를 통해 비동기 작업을 효율적으로 관리할 수 있다는 장점을 가지고 있다. 리액트와 리덕스를 함께 쓰는 경우 아래와 같은 방식으로 데이터를 처리한다.
Redux-saga는 리덕스 미들웨어 중 하나로 특정 액션이 디스패치 되었을 때, 정해진 로직에 따라 다른 액션을 디스패치 할 수 있으며 리덕스의 비동기 작업 처리를 도와주는 라이브러리이다. redux-saga는 데이터 처리 중 발생하는 사이드 이팩트를 효율적으로 처리하고 쉽게 테스트를 할 수 있게 만드는 목표를 가지고 많이 사용하는 편이다.
튜토리얼로 간단한 뉴스 어플리케이션을 만들어 보면서 실습해 보려고 한다. 기초적인 부분은 생략하고 중요한 부분 위주로 설명을 진행한다.
먼저 디렉토리 구성을 보면 다음과 같다.
가장 먼저 볼 부분은 src/index.tsx 코드이다.
기존에 Redux-saga를 쓰지 않는 어플리케이션의 경우 사실 index.tsx는 그냥 App.tsx를 렌더링 해 주기만 하면 된다. 우리는 이 프로젝트에서 redux와 redux-saga를 쓰기로 하였으므로, redux 구조를 위해 line 14에서 스토어를 생성하여 리듀서와 미들웨어를 결합시켜 주었다. 그리고 redux-saga의 createSagaMiddleware() 함수를 가지고 saga를 실행시킨다.
다음은 src/components/Button.tsx 이다.
버튼을 클릭하면 이벤트가 발생하는데 그 이벤트를 통해 getNews 액션 객체가 생성된다. 그 액션이 디스패치 되어서 리듀서로 전달이 된다. react-redux의 내장함수인 connect는 리액트 컴포넌트들에서 리덕스 스토어에 접근할 수 있도록 연결하는 역할을 한다.
이번에는 리듀서 코드를 살펴보자. src/reducers/index.ts 이다.
리듀서는 액션을 받아서 스토어를 변경한 뒤 리턴해 주는 역할을 한다. 따라서 case에 따라 다른 액션을 처리하게 되는데, GET_NEWS 액션의 경우 loading 프로퍼티를 스토어에 true로 저장하게 된다.
다음은 src/sagas/index.ts 이다.
saga 코드에서는 비동기로 뉴스 데이터를 불러오고 그 과정을 처리하는 역할을 한다. 먼저 GET_NEWS 액션이 실행이 되면 가장 마지막 GET_NEWS 액션을 기다렸다가, 그 때 fetchNews() 제너레이터 함수를 실행한다. 이 때는 loading = true 상태이고 로딩 스니펫이 돌아가게 된다.
뉴스 데이터를 API를 사용하여 불러오고 패치가 완료되면 그 때 NEWS_RECEIVED 객체를 리듀서로 보낸다. 그러면 loading = false가 되면서 스니펫은 사라지고 가져온 뉴스 데이터가 스토어에 저장된다. 스토어의 값을 받아 로딩 스니펫과 뉴스 아이템이 보여질 수 있도록 컴포넌트를 구현하였다.
이 프로젝트의 소스코드는 아래에서 확인할 수 있다.
https://github.com/dev-owen/redux-saga-ts
간단하게 리액트, 타입스크립트, 리덕스, 리덕스 사가를 가지고 튜토리얼 어플리케이션을 만들어 보았다. 직접 만들어 보면서 조화롭게 사용할 수 있기를 바란다.
'Web Frontend Developer' 카테고리의 다른 글
[React] ref를 통한 DOM에 이름달기 (1) | 2020.07.31 |
---|---|
[React] 클래스형 컴포넌트 vs 함수형 컴포넌트 (2) | 2020.07.01 |
Babel이란 무엇인가? (2) | 2020.06.22 |
<FE면접질문> #6. 운영체제 (0) | 2020.06.16 |
Webpack이란 무엇인가? (0) | 2020.06.15 |