[TIL][React] Redux

ddoni·2021년 2월 14일
1

Redux

리덕스를 사용하는 이유?

부모-자식 관계가 아닌 컴포넌트와 깊이 있는 컴포넌트에 상태를 전달하기 위해 연결시키는 것과 애플리케이션 전체에서 참고하고 싶은 상태를 모든 컴포넌트에 전달하는 것이 불편하여 전역 상태 관리를 하기위한 리덕스 라이브러리를 사용할 수 있다.

✨ 내가 개발하는 프로그램에 리덕스가 꼭 필요한지 리액트 자체적인 기능 혹은 다른 라이브러리의 도움 받는 것이 훨씬 편한지 고심해보고 사용할 것!

리덕스 라이브러리 설치

npm install redux react-redux --save

리덕스의 세가지 원칙

  1. 전체 상태 값이 하나의 자바스크립트 객체로 표현된다

    전체 상태 값은 자바스크립트 객체로 표현되는대 표현된 객체를 직렬화해서 서버와 클라이언트가 프로그램의 전체 상태값을 주고 받을 수 있다. 애니메이션을 위한 데이터, 문자열 입력창의 상태값은 컴포넌트 내에서 관리하는 것이 더 좋다

  2. 상태값은 불변객체로 관리한다

  3. 리듀서에 의해서만 상태값을 변경해야한다

리덕스 컨셉

  1. 폴더구조 store → reducers, actions 폴더 생성

    각 폴더에는 index.js 파일을 생성하고 필요한 리듀서에 따라 더 생성한다

  2. 액션 함수 생성

    액션은 type 속성을 가진 자바스크립트 객체 형태이다

    액션 생성 함수는 액션 객체를 생성하는 역할을 하는 자바스크립트 함수이다

    액션 객체를 dispatch 메서드에 넣어서 호출하게 되는데(useDispatch 사용) 이는 리듀서를 거쳐 스토어를 업데이트 한다.

    //먼저 액션 생성 함수를 정의해준다
    //필요한 액션 2가지 1. 카트에 넣기 2. 카트에서 빼기
    
    export const addCart = (item) => {
      return {
        type: "ADD_ITEM",
        payload: item,
      };
    };
    
    //이미 필터링 된 아이템들을 인자로 전달해줄거임
    export const deleteCart = (items) => {
      return {
        type: "DELETE_ITEM",
        payload: items,
      };
    };
    • useDispatch 란?

      스토어의 내장 함수로 스토어에 액션 객체를 전달하는 함수

      dispatch 인자로는 액션 객체를 전달해야하는데 이는 리듀서로 전달되어 리듀어에 미리 정의해둔 조건문에 따라 스토어가 업데이트 된다.

  3. 리듀서

    액션이 발생했을때 새로운 상태값을 만드는 함수

    //리듀서는 액션 생성 함수가 리턴한 액션 객체를 디스패치 했을때 들어오는 곳이다
    //리듀서문은 보통 switch-case 문으로 작성하게 된다
    
    //인자로 이전 스토어의 상태값과 액션을 전달받는다
    const cartReducer = (state = INITIAL_STATE, action) => {
      switch (action.type) {
        //정의한 액션 생성함수의 타입을 기준으로 케이스를 나눠준다
        //리턴을 해줄때엔 리덕스에선 불변성을 유지해줘야 하므로 이전 상태와 액션생성함수 값을 가져온다
        case "ADD_ITEM":
          return [...state, action.payload];
        case "DELETE_ITEM":
          return [...action.payload];
    
        //위의 경우가 둘다 아닐때에는 스토어를 그대로 리턴한다
        default:
          return state;
      }
    };
    
    export default cartReducer;
    
    const INITIAL_STATE = [
      {
        isChecked: true,
        product_name: "반팔 티셔츠",
        product_id: 1338,
        product_img: "/images/tShirt.jpg",
        price: 23000,
      },
    ];
    //리듀서는 여러개일 수도 있으므로 여러개의 리듀서들이 모일수 있도록 루트 리듀서를 작성해준다.
    
    //하나로 모으기 위해 함수 임포트
    import { combineReducers } from "redux";
    import cartReducer from "./cartReducer";
    
    //접근하기 위해 cartReducer 키값으로 접근 가능하다
    export default combineReducers({ cartReducer });
    
    //리듀서: 스토어를 업데이트 시키는 함수
  4. 스토어

    앱 index.js에서 작성

    스토어는 리덕스의 상태값을 가지는 단일 객체이며 프로그램 어디서든 접근 가능하다

    //스토어를 프로젝트와 연결하기 위해서 아래 컴포넌트 임포트
    import { Provider } from "react-redux";
    //전역 스토어 생성을 위해 함수 임포트
    import { createStore } from "redux";
    import rootReducer from "./store/reducers";
    
    //앱 index.js 파일에 전역 스토어를 생성하고 루트리듀서와 연결을 해줘야 한다. -> 리듀서는 스토어를 업데이트 시키는 함수이기때문에 리듀서를 통해서만 스토어가 업데이트 할 수 있다
    //(스토어를 만든 후에는 반드시 리듀서와 연결을 해줘야한다)
    
    const store = createStore(rootReducer);
    
    {/* Provider 컴포넌트는 전체 컴포넌트를 감싸주고 store를 연결시켜준다 -> store가 필요한 각각의 컴포넌트에서 useDispatch와 useSelect 훅을 통해서 필요한 상태를 업데이트하거나 가져올 수 있다*/}
        <Provider store={store}>
    • useSelector

      스토어의 특정 내용을 가져올 수 있음

2개의 댓글

comment-user-thumbnail
2021년 3월 25일

참 좋은 설명이네요! 감사합니다👍🏻

답글 달기
comment-user-thumbnail
2021년 3월 29일

이해가 잘 됐어요~!

답글 달기