Redux(Redux wrapper) 사용 이유, 방식, 원리 이해하기 Understanding why, how, and how Redux (Redux wrapper) is used

# 시작

Nextjs에서 Redux와 Redux wrapper를 사용하기 위해서 타 블로그를 참고하여 Redux(리덕스)에 대해 정리해보려고 한다.

 

velog.io/@jehjong/Next.js%EC%97%90%EC%84%9C-Redux%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-Redux-wrapper

 

# Redux를 사용하는 이유

 

리액트는 컴포넌트들에 공통적으로 쓰이는 데이터가 흩어져 있기 때문에 부모 컴포넌트에서 데이터를 받아 자식 컴포넌트로 전달해주어야 한다. 컴포넌트끼리 데이터를 전달하는 과정도 매우 복잡하고 오류가 발생하기 쉽다.

 

그래서 규모가 있는 서비스는 중앙 데이터 저장소 Store를 최소한 한 개 만들어 중앙에서 모든 데이터를 관리하며 전달해주는 것이 좋다. 이 Store는 Redux, Context API, Mobx, Apolo 등이 있다.

 
notion image
 

Redux

  • Redux는 원리가 간단하고 모든 수정사항을 기록한다.
  • 모든 히스토리가 기록되어 에러 추적이 쉽고 안정적이다.
  • 코드량이 많다.
  • 앱이 커지면 코드를 쪼개야 하는데 Reducer들을 쪼갤 수 있어 편리하다.(Reducer는 전달 받은 action에 따라 상태를 어떻게 업데이트할지 정의한 함수)
  • 가장 많이 사용된다.

Mobx

  • Mobx는 코드량이 매우 적어 생산성을 높일 수 있다.
  • 실수하면 추적이 어렵다.
  • 중수 이상은 추천되지만 사용률은 낮다.

Context API

  • 앱 규모가 작을 때 권장된다.
  • 큰 규모에서는 Redux, Mobx 추천 : Store는 서버에서 데이터를 받아오는데 이 과정은 비동기다. 서버나 네트워크 에러 시 데이터가 안 올 수 있다. 요청, 성공, 실패 3단계를 구현해야 한다. 컴포넌트마다 코드 중복이 발생한다. 비동기 요청이 많으면 Context API도 같아진다. 따라서 Redux, Mobx가 편하다.
 
 
npm i redux
npm i next-redux-wrapper
 

root/store/configureStore.js

import { createWrapper } from 'next-redux-wrapper';
import {createStore} from 'redux';

const configureSotre = () => {
	const store = createStore(reducer);
    return store;
};

const wrapper = createWrapper(configureSotre, {
    debug: process.env.NODE_ENV === 'development,'
});

export default wrapper;

_app.js ( return 내부를 Provider로 감싸야했는데 지금은 redux가 알아서 감싸주니 비워두어야 한다 )

import wrapper from '../store/configureStore.js`

// ,,,


export default wrapper.withRedux(Nodebird);
//wrapper로 감싸줘야 프로젝트의 모든 컴포넌트와 페이지에 적용된다

# Redux 원리

notion image

state : 앱의 상태를 객체 형식으로 표현한다.

action : 변경하고 싶은 내용을 action으로 만든다. ( type : action 이름, data : 변경 사항

action dispatch

dispatch된 action을 reducer에 따라 처리한다. ( 바꾸고 싶은 값에 action.data를 넣어준다. )

중앙관리저장소에 앱의 전체 상태를 하나의 객체로 표현한다

{
  name: 'zerocho',
  age: '27',
  password: 'babo'
}

action을 생성해서 무엇을 변경할지 변경사항마다 작성한다.

{
    type: 'CHANGE_NICKNAME'// action이름
    data: 'boogicho'// 변경될 데이타값
  }
  {
    type: 'CHANGE_AGE'
    data: 30,
  }

action을 dispatch하면 reducer에 따라 store의 데이터가 변경된다.

reducer에 데이터를 어떻게 변경해야 하는지 정의해준다.

switch (action.type) {
    case 'CHANGE_NICKNAME'://action의 typereturn {//새로운 객체를 리턴
        ...state,//유지할 state들은 그대로 사용
        name: action.data,//변경할 state를 action.data로 바꿔준다
      }
    case 'CHANGE_AGE'://또 다른 action 처리를 정의return {
        ...state,
        age: action.data,
      }
  }

지정한 데이타만 변경된 채로 새로운 객체가 만들어지고 그 객체를 가져다 쓰는 방식

새로운 객체를 만드는 이유

새로운 객체를 만들면 변경 전과 후를 모두 기록할 수 있다. 객체 내의 바뀌지 않는 데이터는 이전 것 참조.

바뀌는 데이터만 새로 만들고 유지하는 데이터는 참조하는 방식이다.