본문 바로가기
리액트 (React)/Route, Redux

리액트 리덕스 모듈 생성 (덕스 구조)

by 후닝훈 2021. 9. 3.
반응형

덕스(Ducks) 구조

  • 보통 리덕스를 사용할 때는, 모양새대로 action, actionCreator, reducer를 분리해서 작성한다. 예를 들어 액션은 액션끼리, 액션생성함수는 액션생성함수끼리, 리듀서는 리듀서끼리 작성한다.
  • 하지만, 덕스 구조는 모양새로 묶는 대신 기능으로 묶어서 작성한다. 예를 들어 같은 기능을 가진 action, actionCreator, reducer을 한 파일에 넣는 것이다.
  • 덕스 구조의 예시는 아래와 같다
// widgets.js

// Actions
const LOAD   = 'my-app/widgets/LOAD';
const CREATE = 'my-app/widgets/CREATE';
const UPDATE = 'my-app/widgets/UPDATE';
const REMOVE = 'my-app/widgets/REMOVE';

// Reducer
export default function reducer(state = {}, action = {}) {
  switch (action.type) {
    // do reducer stuff
    default: return state;
  }
}

// Action Creators
export function loadWidgets() {
  return { type: LOAD };
}

export function createWidget(widget) {
  return { type: CREATE, widget };
}

export function updateWidget(widget) {
  return { type: UPDATE, widget };
}

export function removeWidget(widget) {
  return { type: REMOVE, widget };
}

// side effects, only as applicable
// e.g. thunks, epics, etc
export function getWidget () {
  return dispatch => get('/widget').then(widget => dispatch(updateWidget(widget)))
  • Action Creator는 컴포넌트들에서 불러와서 사용하기 때문에 export 키워드를 붙여준다.
  • export와 export default의 차이점은 export default는 임포트할 때 중괄호 없이 불러올 수 있고 export만 붙어 있는 것은 중괄호 안에 콤마(,)로 엮어서 가져올 수 있다.
  • export default로 내보낼 수 있는 것은 파일당 하나이다!
  • Reducer를 export default로 빼줄 것이기 때문에 Action Creator들은 export로 빼준다.

 

리덕스 모듈 예제

yarn add react-router-dom
yarn add redux react-redux

 

 

bucket.js 모듈 생성 (redux/modules/bucket.js)

  • src 폴더 아래에 redux라는 폴더를 만들고, 그 안에 modules라는 폴더를 만들자.
  • modules 아래에 bucket.js라는 리덕스 모듈을 만들어보자.
  • bucket.js는 버킷리스트를 LOAD, CREATE하는 2가지 상태 변화를 처리하는 리덕스 모듈이다.
  • create 기능의 경우 ActionCreator에서 리턴하는 객체에서 타입뿐만 아니라 추가할 값이 필요하다.

 

Action 생성

- 버킷리스트를 가져오는 것, 생성하는 것 2가지가 필요하다.

const LOAD = 'bucket/LOAD';
const CREAT = 'bucket/CREATE';

 

initialState 생성

- 초기 상태값 생성

const initialState = {
  list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
};

 

Action Creactor 생성

- 액션 함수를 컴포넌트에서 불러오기 때문에 export 사용

- export defualt 는 reducer에 사용할 것이기 때문에 export로만 사용.

- bucket은 input text 에서 가져온 text 이름이다.

export const loadBucket = (bucket) => {
    return { type: LOAD, bucket };
}
// load는 반드시 bucket 을 가져올 필요는 없다.

export const createBucket = (bucket) => {
    return {type: CREATE, bucket};
}

 

cf) export default pick 한 것은 불러올때 import pick

   그냥 export pick 은 import { pick } 으로 임포트한다.

 

Reducer 생성

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    // do reducer stuff
    case "bucket/LOAD":
        return state;
  
      case "bucket/CREATE":
        const new_bucket_list = [...state.list, action.bucket];
        return { list: new_bucket_list };
        
    default: return state;
  }
}

 

bucket.js 완성코드

// bucket.js

// Actions
const LOAD = 'bucket/LOAD';
const CREAT = 'bucket/CREATE';

// initialState
const initialState = {
    list: ["영화관 가기", "매일 책읽기", "수영 배우기"],
}


// Action Creaters
// 액션 함수를 컴포넌트에서 불러오기 때문에 export 사용
// export defualt 는 reducer에 사용할 것이기 때문에 export로만 사용.
export const loadBucket = (bucket) => {
    return { type: LOAD, bucket };
}

export const createBucket = (bucket) => {
    return {type: CREATE, bucket};
}


// Reducer
// 아무것도 넘기지 않으면 기본값을 넘기는것.
export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    // do reducer stuff
    case "bucket/LOAD":
        return state;
  
      case "bucket/CREATE":
        const new_bucket_list = [...state.list, action.bucket];
        return { list: new_bucket_list };
        
    default: return state;
  }
}

 

 

Store 생성

  • redux 폴더 아래에 configStore.js 파일을 만들고 스토어를 만들어보자.
  • 한 프로젝트에는 스토어가 하나만 있어야 한다.또한, 스토어에는 리듀서가 하나만 있어야 한다. 

 

configStore.js 생성

import { createStore, combineReducers } from "redux";
import bucket from './modules/bucket';
import { createBrowserHistory } from "history";

// 브라우저 히스토리를 만들어준다.
export const history = createBrowserHistory();
// root 리듀서를 만들어준다.
// 나중에 리듀서를 여러개 만들게 되면 이곳에 추가한다.
const rootReducer = combineReducers({ bucket });

// 스토어를 만든다.
const store = createStore(rootReducer);

export default store;

 

- Store은 하나만 사용해야하기 때문에, 후에 여러개의 reducer을 생성한다면, reducer을 합쳐줘야 한다.

- 그 과정이 combineReducers 이다.

const rootReducer = combineReducers({ a, b, c });

 

 

반응형

댓글