본문 바로가기
next+ts

next+ts Redux reducer(SAGA제외) 전체 코드 둘러보기

by 멈추지않아 2022. 5. 9.

data

import axios from "axios";
import { useRouter } from "next/router";
import { useEffect } from "react";
import data from ".";
import { da } from "../../type";
import {
  Delete,
  Increase,
  LOGIN_FAIL,
  LOGIN_PENDING,
  LOGIN_SUCCESS,
  LOGOUT,
  Update,
} from "../actions/actionTypes";
import { ActionProps, CounterState, LoginData } from "../types/state";

export const initialState: CounterState = {
  data: [
    {
      idx: "1",
      currentform: "first",
      maker: "admin",
      text: {
        title: "노래방",
        date: "2022.04.17",
        time: "12.14",
        address: "경북 구미시",
        content: "노래방 ㄱㄱ",
        tags: ["놀자", "놀자", "놀자"],
      },
    },
    {
      idx: "2",
      currentform: "first",
      maker: "admin",
      text: {
        title: "노래방",
        date: "2022.04.17",
        time: "12.14",
        address: "경북 구미시",
        content: "노래방 ㄱㄱ",
        tags: ["놀자", "놀자", "놀자"],
      },
    },
  ],
  common: {
    login: "admin",
  },
};

const Main = (state = initialState, action: ActionProps) => {
  switch (action.type) {
    case Increase:
      return { ...state, data: [...state.data, action.payload] };
    case Delete:
      state.data = state.data.filter((state) => {
        if (state.idx != action.payload) {
          return state;
        }
      });
      return { ...state };
    case LOGIN_PENDING:
      return { ...state };
    case LOGIN_SUCCESS:
      state.common.login = (<LoginData>action.payload).id;
      action.router.push("/");
      return { ...state };
    case LOGIN_FAIL:
      console.log("로그인 실패");
      alert("로그인 실패");
      return { ...state };
    case LOGOUT:
      console.log("로그아웃");
      return { ...state, common: { login: "admin" } };
    case Update:
      state.data = <da[]>state.data.map((res) => {
        if (res.idx == (action.payload as da).idx) {
          return action.payload;
        }
        return res;
      });

      return state;
    default:
      return { ...state };
  }
};

export default Main;
export type mainState = ReturnType<typeof Main>;
initialstate로 기본값을 설정해주고 main함수에서 state에 데이터 action에는 action에서 넘겨받은 type payload router등을 저장하고 있습니다.
switch를 활용해서 type에따라 다른 작업을 하게 설정했습니다.
case Increase:
      return { ...state, data: [...state.data, action.payload] };
이부분은 기존 데이터를 그대로 가져오는데 data 부분을  수정하는 겁니다. 즉 ...state.data=기존의 data 부분 여기세 action.payload를 더한 배열 값음 data에 저장하는 결과 입니다.
    case Delete:
      state.data = state.data.filter((state) => {
        if (state.idx != action.payload) {
          return state;
        }
      });
      return { ...state };
이 부분은 filter로 받은 payload와 같은 idx빼고 state.data의 데이터를 저장하고 그걸 다시 데이터로 저장하게 됩니다.
    case LOGIN_PENDING:
      return { ...state };
이부분은 로그인 실행하기전에 실행할 내용있으면 사용하기위한 공간입니다.
    case LOGIN_SUCCESS:
      state.common.login = (<LoginData>action.payload).id;
      action.router.push("/");
      return { ...state };
로그인이 성공하면 받은 데이터를 common.id의 로그인 부분에 id만 저장하게 됩니다.
그리고 router로 이동하고 데이터를 저장합니다.
    case LOGIN_FAIL:
      console.log("로그인 실패");
      alert("로그인 실패");
      return { ...state };
로그인 함수 실행도중 오류가 나오면 실행하는 구간입니다.
    case LOGOUT:
      console.log("로그아웃");
      return { ...state, common: { login: "admin" } };
로그 아웃하면 common부분을 admin으로 변경하여 로그아웃 상태를 알수 있도록 합니다.
    case Update:
      state.data = <da[]>state.data.map((res) => {
        if (res.idx == (action.payload as da).idx) {
          return action.payload;
        }
        return res;
      });

      return state;
이부분은 데이터를 받아서 idx가 같은 부분의 데이터를  받아온 데이터로 변환하여 데이터를 저장하게 합니다.
    default:
      return { ...state };

이부부은 위에 해당되지 않으면 그냥 그대로 보내버리라는 뜻입니다.

export type mainState = ReturnType<typeof Main>;

이것은 Main 함수의 반환 타입을 type으로 만들어버리는 것입니다.

index

import { combineReducers } from "redux";
import { CounterState } from "../types/state";
import main from "./data";

const data = combineReducers({
  main,
});

export default data;

export type RootState = ReturnType<typeof data>;

combineReducer를 활용해서 reducer가 여러개이면 합쳐서 하나의 저장소로 활용하기 위한 것입니다. 

const data = combineReducers({
  main,
});
이런식으로 대괄호 안에 switch를 활용해서 사용하는 함수를 넣으면 데이터가 들어가게 됩니다. 따라서 함수를 여러개 넣어서 만들면 여러 데이터가 들어가게 됩니다.