본문 바로가기
React

React(57) Redux 로 객체배열 저장하기 (redux 상태관리)

by 새발개발JA 2022. 2. 1.
반응형

처음에는 리덕스의 개념을 이해하는 것이 쉽지 않았다. 하지만 코드를 보며 몇 번 적용해보니 기본적인 개념이 이해가 되었다.

 

 

내가 생각하는 리덕스란

보통 데이터를 주고받을 때, 부모 - 자식 컴포넌트로 데이터를 전달하지만, 이곳저곳에서 다양하게 공통으로 쓰이는 글로벌 데이터라면,

자식-부모-조부모-삼촌-조카 이런식으로 여러 컴포넌트로 복잡하게 전달해줘야 할 것이다.

글로벌 저장소에 데이터를 저장해놓고 필요할때 어디서든 간단하게 소환할 수 있도록 하는 라이브러리가 리덕스(Redux) 라고 생각한다.

 

 

Redux-persist 란 

리덕스를 사용해서 글로벌 저장소에 들어간 데이터는 아쉽게도 새로고침 한방이면 초기화되며 수명을 다한다.

이때 Web Storage에 저장해줘야 하는데 저장과 삭제를 쉽게 해주는 라이브러리가 Redux-persist 이다. 

  • localStorage에 저장하고 싶으면 → import storage from 'redux-persist/lib/storage
  • session Storage에 저장하고 싶으면 → import storageSession from 'redux-persist/lib/storage/session

 

리덕스 기본 개념에 대해서 햇갈리신다면 개념익히고 오기 ↓↓↓ 

 

React(30) Redux 란

Redux 란 리덕스 는 React 의 상태관리 라이브러리이다. 즉, 데이터를 더욱 쉽게 이쪽저쪽으로 보내주고 관리도 해주는 도우미이다. React 는 View 만을 책임지는 라이브러리이기 때문에 데이터를 어

devbirdfeet.tistory.com

 

 


 

React(57) Redux 로 객체 저장하기 (redux 상태관리)

자 이제 Redux 로 Redux-persist 를 사용하여 저장해보자

 

model/Reply.ts

먼저 인터페이스에 타입을 선언해주자

export interface Reply { // 댓글의 객체 타입을 선언
  id?: number;
  reply: string;
  createdAt?: string;
  updatedAt?: string;
  deletedAt?: string;
}

 

redux/Reply.ts

여기서 타입과 액션 그리고 리듀서를 선언한다. (얘네들을 얽히섥히 관계가 나름있는데 ...)

타입을 선언하면, → 타입을 액션에 넣고, → 리듀서에서 액션 타입에 따라 뭘 실행할 지 결정한다.

import { Reply } from 'model/Reply'; // 위에서 선언한 타입을 가져와서 사용하자

// 타입 선언
type replyAction = ReturnType<typeof initReply> | ReturnType<typeof setReply>;

const INITREPLY = 'reply/INITREPLY' as const; 
const SETREPLY = 'reply/SETREPLY' as const;

const initialState: Reply[] = []; // 댓글 리스트를 받기위해 타입과 초기값으로 배열[]선언

// 액션들
export const initReply = (): { type: string; payload?: null } => ({
  type: INITREPLY		// 초기화 해주는 액션이므로 타입만 존재하고 페이로드는 없다
});

export const setReply = (replies: Reply[]): { type: string; payload: Reply[] } => ({
  type: SETREPLY,		// 타입이 분기점 역할을 해서 아래 리듀서에서 분기한다
  payload: replies, 		// 페이로드에는 객체배열을 담은 댓글 리스트 객체가 들어간다
});

// 리듀서       (↓ 초기값과, 액션을 인자로 넣어주고)
function Reply(preState: Reply[] = initialState, action: replyAction): Reply[] {
  switch (action.type) { 			// 액션의 타입에 따라 다른 케이스가 실행된다!
    case INITREPLY:				// 타입이 [이닛리플] 이면 	
      return [];				// → 빈 배열 값이 리턴되고
    case SETREPLY:				// 타입이 [셋리플] 이면
      return <Reply[]>action.payload; 		// → 액션이 가진 값(페이로드)이 리턴된다
    default:					// 디폴트는 (빼놓으면 섭하지)
      return preState;				// → 초기화된 값으로 리턴!
  }
}

export default reply;

 

redux/index.ts

여기서는 여러 리듀서들을 모아모아~ 루트리듀서를 만든다. 

이제 어디서든 루트 리듀서를 소환하기만 하면 당신은 글로벌 데이터를 사용할 수가 있는 것이다.

import { CombinedState, combineReducers } from '@reduxjs/toolkit';
import { persistReducer } from 'redux-persist';
import { PersistPartial } from 'redux-persist/es/persistReducer';
import storage from 'redux-persist/lib/storage';
import hardSet from 'redux-persist/lib/stateReconciler/hardSet';
import reply from 'redux/Reply'; // 여기서 가져오기

const rootPersistConfig = { 	// 루트 config 설정
  key: 'root',
  storage,
  whitelist: ['user', 'payment', 'reply'],
  stateReconciler: hardSet,
};

const replyPersistConfig = {   // 댓글 config 설정
  key: 'reply',
  storage,
  stateReconciler: hardSet,
};

... 생략 ...

const rootReducer = combineReducers({ // 루트리듀서 선언 (컴바인리듀서 안에 각각의 리듀서들 넣어 합쳐주기)
  reply: persistReducer(replyPersistConfig, reply), // 이런식으로 persistReducer에 넣어준다.
  user: persistReducer(userPersistConfig, user),
  payment: persistReducer(paymentPersistConfig, payment),
});

export type rootState = ReturnType<typeof rootReducer>;
export default persistReducer<any, any>(rootPersistConfig, rootReducer);

 

 

ReplyComponent.tsx

실제로 쓰이는 컴포넌트에서 데이터를 글로벌화 시키기 위해 dispatch 를 통해 redux 에 저장시켜준다.

import { ReactElement, useState } from 'react';
import { useDispatch } from 'react-redux'; // 필요한 redux 애들 임포트
import { setReply } from 'redux/Reply';	   // redux에서 만들었던 set함수 임포트

const ReplyComponent = (): ReactElement => {
  const replyList: Reply[] = [{		   // 댓글 리스트
  	id: 1,
    reply: '첫번째 댓글 감사합니다.',
    createdAt: '2022-01-11',
    updatedAt: '2022-01-15',
    deletedAt: '2022-01-17'
  },{
  	id: 2,
    reply: '두번째 댓글 감사합니다.',
    createdAt: '2022-01-11',
    updatedAt: '2022-01-20',
    deletedAt: '2022-01-25'
  }]
  const dispatch = useDispatch(); 	   // 디스패치를 준비해주자  
  dispatch(setReply(list)); 		   // 그 [list]를 디스패치로 리덕스 속에 저어장	       
  
  ... 생략 ...
}
export default ReplyComponent

 

 

결과화면

크롬 리덕스 툴로 확인하니 아주 잘 저장되었다!

 

 

 

 

ref: https://kyounghwan01.github.io/blog/React/redux/redux-persist/#reducer%E1%84%8B%E1%85%A6-persist-store-%E1%84%8C%E1%85%A5%E1%86%BC%E1%84%8B%E1%85%B4

반응형

댓글