프로젝트/헬스 다이어리 앱

[헬스 다이어리 앱 개발] 6편 - Redux Toolkit으로 데이터 관리하기

Junheehee 2022. 9. 17. 00:35

본격적으로 앱에 기능들을 추가하기에 앞서서

지금까지 만든 앱 상황을 정리해봐야겠다.

블로그의 쓴 내용말고도 짬짬이 몇가지를 추가했다.

 

 

홈 화면

우선 홈 스크린이다.

운동한 날짜를 보여주는 달력과 오늘 운동을 기록하는 버튼이 있다.

달력과 운동하기 버튼 사이에 며칠 연속으로 운동하고 있는지 보여주는 칸도 추가할 예정이다.

 

 

다이어리 화면

달력에 날짜를 클릭했을 때 보여지는 다이어리 화면이다.

날짜는 탑바로 뺄 예정이고 그날 한 운동들을 보여줄 거다.

 

운동 기록하기 버튼은 깜빡하고 기록을 하지 않았을 때를 위한 버튼이다.

만약에 이미 기록이 있다면 '기록 수정하기'라고 텍스트를 바꿔서 보여줄 것이다.

 

 

기록 추가 화면

다이어리 화면에서 '운동 기록하기' 버튼을 클릭하거나 홈 화면에서 '운동하기' 버튼을 클릭했을 때 들어가지는 기록 추가 화면이다.

탑바는 뒤로가기 버튼과 해당 날짜, 완료하기 버튼으로 이루어져 있다.

 

 

 

 

이제 헬스 기록을 추가하고 수정하는 기능을 구현할 것인데,

데이터 관리는 Redux Toolkit을 사용할 거다.

리액트 어플리케이션을 개발하다보면 props를 여러 겹의 하위 컴포넌트로 넘겨줄 일이 많고 이는 굉장히 번거롭다.

이 때 Redux 같은 라이브러리를 이용하면, props를 넘기지 않고도 데이터를 전역에서 접근할 수 있게 된다.

Redux Toolkit은 Redux를 개량한 라이브러리다.

 

[스터디 with 실전 리액트 프로그래밍] 15편 - 리덕스

4장은 리액트 활용법을 다루는데, 블로그에 포스팅하기 애매해서 따로 공부했다. 5장은 클래스형 컴포넌트를 다룬다. 클래스형 컴포넌트 자체가 레거시여서 기존 코드를 작업하지 않는 이상 클

junhee-hee.tistory.com

 

 

코드는 공식문서를 참고했다.

 

Quick Start | Redux Toolkit

 

redux-toolkit.js.org

 

 

먼저 redux toolkit을 설치하자. 

$ yarn add @reduxjs/toolkit react-redux

 

 

그 다음 store.ts를 만들자.

// src/app/store.ts

import { configureStore } from "@reduxjs/toolkit";
import recordReducer from "../features/record/recordSlice";

export const store = configureStore({
  reducer: {
    record: recordReducer,
  },
});

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;

 

 

 

slice도 만들자.

// src/features/record/recordSlice

import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";

interface SetState {
  weight: number;
  num: number;
}

interface HealthState {
  name: string;
  sets: Array<SetState>;
}

export interface RecordState {
  date: string;
  startTime: string;
  endTime: string;
  healths: Array<HealthState>;
}

const initialState: RecordState[] = [];

export const recordSlice = createSlice({
  name: "records",
  initialState,
  reducers: {
    updateRecord: (state, action: PayloadAction<RecordState>) => {
      const index: number = state.findIndex(
        (item) => item.date === action.payload.date
      );
      if (index == -1) {
        state.push(action.payload);
      } else {
        state[index] = action.payload;
      }
    },
  },
});

// Action creators are generated for each case reducer function
export const { updateRecord } = recordSlice.actions;

export default recordSlice.reducer;

초기값도 세팅하고, state를 업데이트하는 reducer도 정의했다.

reducer는 기록을 수정하거나 추가하는 updateRecord만 만들어 놨다.

 

 

이제 state애 접근할 컴포넌트를 provider로 감싸면 된다.

모든 컴포넌트에서 접근 가능하게 만들기 위해 app.js에서 provider 컴포넌트를 최상위에 두자.

 

 

잘 적용되었는지 확인하기 위해 Home 스크린에서 react-redux의 useSelector로 state를 가져온 뒤 출력해봤다.

잘 출력되었다.

react-redux의 useDispatch를 이용해 리듀서 updateRecord도 문제 없이 작동하는 것을 확인하였다.

 

 

 

 

나중에는 데이터를 핸드폰 로컬에서 관리하는게 아니라, 필요할 때마다 서버에 요청을 하는 방식으로 바꿔야겠다.

(백업도 자동으로 할겸)

 

 

 

 

코드

 

 

GitHub - junhee-won/health-diary-app

Contribute to junhee-won/health-diary-app development by creating an account on GitHub.

github.com