본문 바로가기
SPA/React

[React] 함수형 컴포넌트 + 타입스크립트 환경에서 Redux 사용하기

by J4J 2021. 8. 9.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 함수형 컴포넌트 + 타입 스크립트 환경에서 redux 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

들어가기에 앞서 redux가 무엇인지에 대해 궁금하신 분은 여기를 참고해주시면 됩니다.

 

 

 

Redux 사용 방법

 

이번에 redux를 설정하여 최종적으로 확인해볼 것은 다음과 같습니다.

 

  • store에 num값을 저장
  • 파라미터 값만큼 num의 값을 증가시키는 액션 함수 정의
  • 파라미터 값만큼 num의 값을 감소시키는 액션 함수 정의
  • 증가와 감소 버튼을 누를 경우 num의 값이 실시간으로 변화되는 것을 확인

 

 

 

[ 1. 패키지 설치 ]

 

$ npm install redux react-redux @types/react-redux redux-devtools-extension

 

 

 

[ 2. action함수 파일 생성 ]

 

action함수 파일을 따로 생성하는 것은 취향에 따른 선택적인 요소입니다.

 

저 같은 경우는 redux를 별로 사용하지 않는 상황에서는 이번에 작성할 것처럼 하나의 파일에 타입 / 액션 함수 인터페이스 / 액션 함수를 모두 몰아서 넣습니다.

 

하지만 일반적으로 타입 / 액션 함수 인터페이스 / 액션 함수를 정의하는 파일들을 각각 분리하여 관리하고는 합니다.

 

이 외에도 여러 방법들이 있으니 참고만 해주시면 될 것 같습니다.

 

 

 

그럼 저는 위에서 언급한것 처럼 이번엔 하나의 파일에 모두 몰아넣을 것이고 파일의 위치는 /src/modules에 actions.tsx를 생성해보겠습니다.

 

// 타입 정의
export const increase = 'increase';
export const decrease = 'decrease';

// 액션 함수 인터페이스 정의
export interface IincreaseAction {
    type: typeof increase;
    payload: number;
}

export interface IdecreaseAction {
    type: typeof decrease;
    payload: number;
}

// 액션 함수 정의
export const increaseAction = (res: number): IincreaseAction => {
    return {
        type: increase,
        payload: res,
    }
}

export const decreaseAction = (res: number): IdecreaseAction => {
    return {
        type: decrease,
        payload: res,
    }
}

// reducer에서 사용될 action 타입 모음
export type Iactions = IincreaseAction | IdecreaseAction;

 

 

반응형

 

 

[ 3. reducer정의 파일 생성 ]

 

reducer정의 파일은 /src/modules에 numberReducer.tsx로 생성하여 만들어보겠습니다.

 

import { decrease, Iactions, IdecreaseAction, IincreaseAction, increase } from "./actions"

export interface InumberState {
    num: number;
}

// store에 저장되어 있는 state 값
const numberState: InumberState = {
    num: 0
}

const numberReducer = (state: InumberState = numberState, action: Iactions) => {
    switch(action.type) {
        // 타입이 increase인 액션 함수가 넘어올 경우
        case increase: {
            return {
                ...state, // 현재 state 유지
                num: state.num + (action as IincreaseAction).payload, // num값만 수정
            }
        }

        case decrease: {
            return {
                ...state,
                num: state.num - (action as IdecreaseAction).payload,
            }
        }

        default: {
            return {
                ...state,
            }
        }
    }
}

export default numberReducer;

 

 

 

[ 4. 사용되는 reducer를 묶어주는 파일 생성 ]

 

redux를 이용하여 개발을 하다 보면 한 개의 reducer파일만 생성하는 일은 드문 상황입니다.

 

일반적으로 여러 개의 reducer파일들을 생성하고는 하는데 이렇게 만들어진 파일들을 하나의 store에 등록하기 위해 reducer를 묶어주는 행동이 필요해집니다.

 

이를 위한 파일을 /src/modules에 indexReducer.tsx로 생성해보겠습니다.

 

import { combineReducers } from 'redux';
import numberReducer, { InumberState } from './numberReducer';

// state interface 묶어주기
export interface IindexState {
    numberReducer: InumberState;
    // reducer 2: Istate;
    // reducer 3: Istate;
    // ...
}

// reducer 묶어주기
const indexReducer = combineReducers({
    numberReducer,
    // reducer 2,
    // reducer 3,
    // ...
});

export default indexReducer;

 

 

 

[ 5. store 등록 ]

 

만들어진 reducer들을 이제 store에 등록해주는 과정이 필요합니다.

 

초기 파일 셋팅을 할 때 폴더 최상단에 만들어지는 index.tsx를 다음과 같이 수정해주시면 됩니다.

 

import * as React from 'react';
import ReactDom from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import indexReducer from './modules/indexReducer';

const store = createStore(indexReducer, composeWithDevTools());

ReactDom.render(
    <Provider store={store}>
        {/* BrowserRouter를 사용할 경우 프로그래밍 되는 위치 */}
        <App />
    </Provider>,
    document.querySelector('#root')
);

 

 

728x90

 

 

[ 6. redux가 사용되는 파일 ]

 

위와 같이 설정을 마쳤다면 redux를 사용할 수 있는 환경은 마련되었습니다.

 

폴더 최상단에 존재하는 App.tsx파일에서 store에 저장되어 있는 num값을 조작해보겠습니다.

 

import * as React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { decreaseAction, increaseAction } from './modules/actions';
import { IindexState } from './modules/indexReducer';

const App = (): JSX.Element => {
    const dispatch = useDispatch();

    const num = useSelector((state: IindexState) => state.numberReducer.num); // numberReducer의 state에 저장되어 있는 num값 가져오기

    const onClickIncrease = () => {
        dispatch(increaseAction(3)); // dispatch를 이용하여 action함수를 reducer에 전달
    }

    const onClickDecrease = () => {
        dispatch(decreaseAction(2)); // dispatch를 이용하여 action함수를 reducer에 전달
    }

    return (
        <div>
            <p>현재 값: {num}</p>

            <button onClick={onClickIncrease}>증가</button>
            <button onClick={onClickDecrease}>감소</button>
        </div>
    )
}

export default App;

 

 

 

소스 코드를 위와 같이 한 뒤 서버를 실행시키면 현재 값과 증가 버튼, 감소 버튼이 보이게 됩니다.

 

증가 버튼을 누를 경우 현재 값이 3만큼 증가되는 것을 실시간으로 확인할 수 있고 감소 버튼을 누를 경우 현재 값이 2만큼 감소되는 것을 실시간으로 확인할 수가 있습니다.

 

 

실행 화면

 

 

 

Redux 크롬 확장자

 

redux 크롬 확장자 같은 경우는 크롬을 통해 redux가 적용되는 것을 실시간으로 확인할 수 있도록 도와줍니다.

 

크롬 확장자를 사용하기 위해서는 우선 여기에 들어가서 redux devtools 플러그인을 설치해주셔야 합니다.

 

그리고 이미 위의 단계에서 redux devtools과 관련된 패키지를 설치했고 또한 index.tsx파일에 store를 만들어 줄 때 devtools를 등록해줬기 때문에 바로 확인이 가능합니다.

 

 

 

확인 방법은 브라우저에서 F12를 눌러 개발자 도구 창을 들어간 뒤 Redux 탭을 선택해주시면 확인할 수 있습니다.

 

저 같은 경우는 위의 실행 화면에서 실행한 목록들이 다음과 같이 보이고 있습니다.

 

redux 크롬 확장자

 

 

 

파일 구성

 

파일 구성

 

 

 

 

 

 

 

이상으로 함수형 컴포넌트 + 타입스크립트 환경에서 redux 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글