Redux

1. Redux란? 👀

  • 리액트 상태 관리 라이브러리. 전역 상태를 관리할 때 유용함
  • 하나의 스토어에서 데이터를 꺼내쓴다는 개념, 데이터의 모든 상태를 관리한다.
  • 트리구조로 내려오는 컴포넌트 -> 값을 변경하려면 state -> 값 전달 props(단방향, 위에서 아래로) => 비효율적임

    1-2-3-4-5-6-7 와 같은 순차적인 계층구조가 아닌
    1 —store—> 7 스토어를 통해 값을 전달


2. Redux 의 처리 프로세스

컴포넌트 ——dispatch()——> 액션(객체) ---> 리듀서 ---> 스토어 --connect()——> 컴포넌트

Dispatch()

  • 액션 객체를 만드는 함수
    - type이라는 값을 포함하고 있어야 함 : 어떤 동작인지를 지정하는 표기값
    Ex. ADD_COUNT, ADD_CART.. 와 같이 명시적으로 지음. 💡관습적으로 대문자!

액션 Action

  • 어떤 동작(state 변화= 값의 변화)에 대해 선언된 객체

리듀서 Reducer

  • State에 변화를 일으키는 함수(수정해줌)
  • 파라미터 : 현재상태 state값, action -> 전달받은 액션으로 스토어에 들어가서 변경 작업을 함
  • 실질적인 일을 하는 함수

스토어 Store

  • 중앙 통제실과 같은 역할.

  • 프로젝트에 리덕스를 적용한다.
    데이터가 새로운 값으로 변경, 갱신 되면 connect 함수(또는 UseSelector)를 통해 컴포넌트에 전달

  • 구성 : 현재 앱의 State , Reducer, 내장함수

    • State를 수시로 확인, 현재 변경된 상태를 알려 준다. (참고: 자체가 변경되는 것이 아닌 새로운 값이 덧붙여지는 형태임)

    • Store 내장 함수 (1) Dispatch() : reducer한테 액션을 실행하라고 시키는 함수(리듀서에게 액션을 전달. (전달자))

    • Store 내장 함수 (2) Subscribe() 구독 : store를 주시하고 있다가 액션이 디스패치될 때마다 함수를 호출

  • 파라미터: Action -> “액션을 발생시키는 함수.”
  • 스토어가 리듀서 함수를 실행하고 리듀서 함수가 넘긴 액션을 처리해서 새로운 상태로 만들어준다.


<스토어 사용 규칙>

  1. 하나의 프로젝트에 하나의 스토어만 사용
  2. state는 읽기 전용. 고유값은 수정되지 않음
  3. 리듀서는 현재상태의 state 객체 자체를 수정하는 것이 아니고 변화를 일으킨 새로운 상태 객체를 만들어서 반환

3. 프로젝트에 Redux 사용하기

💡 액션 타입, 액션 생성 함수, 리듀서 코드를 작성해야 한다!

1️⃣ 액션 타입 정의(대문자), 액션 생성 함수 만들기

🗂 src>store>actions>index.js
export const addCart = (item) => {
    return{
        type : "ADD_ITEM",
        payload : item//type 외의 나머지값
    }   
}//액션 생성 함수

2️⃣ 초기 상태 및 리듀서 함수 만들기

🗂 src>store>reducers>cartReducer.js
const cartReducer = (state = [], action) => {
    switch(action.type){
        case "ADD_ITEM"://action의 타입이 ADD_ITEM이면
            return[...state, action.payload];//return 값이 있으면 break문 안 써도 됨
        case "DELETE_ITEM"://action의 타입이 DELETE_ITEM이면
            return[...action.payload];//새로 수정되는 것이 아니라 갖고있던 값만 뱉어냄
        default:
            return state;
    }
}

export default cartReducer;

3️⃣ 스토어 만들기

🗂 src>index.js
  • Provider 컴포넌트 사용하여 리덕스 적용
import { createStore } from 'redux';
import rootReducer from "./store/reducers/"
import { Provider } from 'react-redux';

const store= createStore(rootReducer);

ReactDOM.render(
  <React.StrictMode>
    <Provider store= { store }>//💡props로 store를 전달해줘야함!
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

4️⃣ 컴포넌트에서 리덕스 스토어에 접근하기

(1) react-redux의 UseDispatch 훅 사용
-> 컴포넌트 내부에서 스토어의 내장함수인 dispatch를 사용할 수 있게 함

🗂 src>components>ProductItem.js
import React from "react";
import './ProductItem.css';
import { useDispatch } from 'react-redux';
import { addCart } from "../store/actions";

function ProductItem ({ item }){
    const dispatch = useDispatch();
    return(
        <div className="ProductItem">
            <img className="item-image" src={item.product_img} alt="product-image" />
            <div className="item-name"> {item.product_name}</div>
            <div className="item-price">{item.price}</div>
            <button className="add-cart-btn" onClick={()=> dispatch(addCart(item))}>
                <i class="fas fa-plus"></i>
                Add to Cart
            </button>
        </div>
    )
}

export default ProductItem;

(2) react-redux의 UseSelector 훅 사용
-> connect 함수 사용하지 않고 리덕스의 상태 조회

🗂src>components>ProductItem.js
 import { useSelector } from "react-redux";
 function Nav (){
 const navi = useNavigate();
 const cart = useSelector(store => store.cartReducer);
 const cartNum = cart.length;
 return(
     <nav className="Nav">
         <h1 className="nav-title"><Link to="/">HnM</Link></h1>{/* 링크연결 1) Link 컴포넌트 사용 */}
         <i className="fas fa-shopping-cart" onClick={()=> navi("/cart")}>{/* 링크연결 2) 라우터 버전6, navigate 컴포넌트 사용 */}
             <span className="cart-amount">{ cartNum }</span>
         </i>
     </nav>
 )
}

export default Nav
profile
걸음마 개발 분투기

0개의 댓글