Redux with react&typescript

Asher·2021년 11월 22일
0
post-thumbnail

React 환경에서 Redux에 typescript를 적용하는 방법이다.
(Redux toolkit)

React + javascript 환경에서 짜여진 Redux 코드에 typescript를 적용하는 과정을 보여주는 글로, redux 관련 세부 코멘트는 생략한다.

코드는 여기저기 구글링을 하며 짬뽕한 코드이다.
Redux로 상태관리를 하기 위한 최소한의 코드 & 기능 만을 포함한다.
(미들웨어 같은거 없다)

파일을 아래와 같이 생성 및 작성한다. (3개 파일)

1. Store.ts

Redux store, reducer 등을 관리하는 파일이다.
redux-roolkit을 사용했다 (createSlice, configureStore 등)
state는 title과 info(이름, 나이)이고 타입은 코드 안의 interface IState 와 같다.

// Store.ts
import { createSlice, PayloadAction, configureStore } from '@reduxjs/toolkit';

// state interface
export interface IState {
  title: string;
  info: IInfo;
}
export interface IInfo {
  name: string;
  age: number;
}

// createSlice
const documentSlice = createSlice({
  // slice name 설정
  name: 'document',

  // 초기 state 설정
  initialState: {
    title: '초기 정보',
    info: {
      name: '김처음',
      age: 1,
    },
  },

  //reducer 설정
  reducers: {
    setTitle: (state, action: PayloadAction<string>) => {
      state.title = action.payload;
    },
    setInfo: (state, action: PayloadAction<IInfo>) => {
      state.info = action.payload;
    },
  },
});

// configureStore
const store = configureStore({ reducer: documentSlice.reducer });

// export actions
export const { setTitle, setInfo } = documentSlice.actions;

// export store to index.tsx
export default store;

2. index.tsx

react-redux의 provider로 App 컴포넌트를 감싸준다

// index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { Provider } from 'react-redux';
import store from './Reducers';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

3. App.tsx

react-connect를 사용하여 각 components에서 state를 참조하거나, action을 발생시켜(dispatch) state를 변경(reducer 함수 실행)할 수 있다.

typescript를 적용하는 방법 중 react-redux 공식문서에서 제안하는 방법은 connectedProps 를 사용하는 방법이다. (공식문서 / react-redux & typescript)

const mapStateToProps = (state: IState) => {
  return {
    // state
  };
};

const mapDispatchToProps = (dispatch: any) => {
  return {
    // dispatch
  };
};

const connector = connect(mapStateToProps, mapDispatchToProps);

// components 의 파라미터로 들어갈 type (from redux state)
type PropsFromRedux = ConnectedProps<typeof connector>;

export default connector(App);

위와 같이 connector라는 변수에 connect(mapStateToProps, mapDispatchToProps)를 할당하고,
이 변수와 connectedProps를 사용해서 type을 추출하고, 이를 해당 컴포넌트의 type으로 지정한다. (PropsFromRedux)

App.tsx의 전체 코드는 아래와 같다.

// app.tsx
import React, { useState } from 'react';
import { connect, ConnectedProps } from 'react-redux';
import { setTitle, setInfo, IInfo, IState } from './Reducers';

// 아래에서 정의한 type을 적용한다.
function App(props: PropsFromRedux) {
  // redux 변화를 확인하기 위한 코드 (버튼을 누르면 redux state가 업데이트 되고, state가 렌더링된다.)
  const [isTrue, setIsTrue] = useState(true);

  const handleClick = () => {
    if (isTrue) {
      props.setTitle('진짜정보');
      props.setInfo({
        name: '김진짜',
        age: 25,
      });
      setIsTrue(false);
    } else {
      props.setTitle('가짜정보');
      props.setInfo({
        name: '김가짜',
        age: 2500000,
      });
      setIsTrue(true);
    }
  };

  return (
    <>
      <div>
        <h1>This is home component</h1>
        <button onClick={handleClick}>btn</button>
        <p>{props.title}</p>
        <p>{props.info.name}</p>
        <p>{props.info.age}</p>
      </div>
    </>
  );
}

const mapStateToProps = (state: IState) => {
  return {
    title: state.title,
    info: state.info,
  };
};

const mapDispatchToProps = (dispatch: any) => {
  return {
    setTitle: (data: string) => dispatch(setTitle(data)),
    setInfo: (data: IInfo) => dispatch(setInfo(data)),
  };
};

// react-redux connect
const connector = connect(mapStateToProps, mapDispatchToProps);

// components 의 파라미터로 들어갈 type (from redux state)
type PropsFromRedux = ConnectedProps<typeof connector>;

export default connector(App);

4. 확인

타입스크립트와 함께라면 코드를 작성할 때 이렇게 편리하게 작성할 수 있다.

이제 state가 변경이 잘 되는지 확인해보자.

초기화면



btn 클릭!



btn 한 번 더 클릭!

state가 잘 바뀌는 것을 확인할 수 있다.

끝!

(Move to github repository)

profile
Frontend Developer

0개의 댓글