Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

냥냠

[React] React 기초(3) _ Redux 본문

React

[React] React 기초(3) _ Redux

sueeee-e 2024. 7. 16. 14:27

Redux 라이브러리

 

동등한 컴포넌트 사이에서는 어떤 함수를 공유할 수는 없다.

-> 부모가 props 를 통해 자식에게 주는 건 가능 (일방적)

 

부모에서 자식으로 O

자식끼리 공유 X

자식이 부모 X

--> 단방향 통신 + props 남발으로 너무 복잡해짐

 

 

Store(리덕스)에 State를 저장해서 어느 컴포넌트에서든 가져올 수 있게 한다. 

 

component ---useDispatch --> Action -----> Reducer -----> Store 

Store -------useSelector----->component

 

Redux 초기세팅 

//설치 npm install redux, npm install react-redux

//index.js에서 리덕스로 감싸주기  + store 만들기
import { Provider } from "react-redux";
import store from "./redux/store";

<Provider store = {store}>
  <App/>
</Provider>

//리덕스 폴더에 store 컴포넌트 만들기
//store.js

import {creatStore} from 'redux';
import reducer from './reducer/reducer';

let store = createrStore(reducer);

export default store;

//리덕스 폴더 안에 리듀서 폴더 안에 리듀서 컴포넌트 
//reducer.js

let initialState = {            //초기값
  count:0
}

function reducer(state = initialState, action) {
   //내용
}


export default reducer;
//App.js  리덕스를 거쳐서 state를 받아오는 컴포넌트 
import { useDispatch, useSelector } from 'react-redux';

const count = useSelector(state=>state.count)
const dispatch = useDispatch()

const increase= () => {
  dispatch({type:"INCREMENT"})
}


return
  <button onClick={increase}> 증가 </button>


//reducer.js

let initialState = {            //초기값
  count:0
}

function reducer(state = initialState, action) {
   //if else 또는 switch case
   switch (action.type) {
     case "INCREMENT":
       return{...state, count:state.count+1};
     dafault:
       return{...state};
   }
   
}


export default reducer;

가져다 쓰고 싶은 곳에 useSelector 으로 state 받아오면 된다.

//payload (매개변수) 예제

//App.js
let count = useSelector((state = > state.count);
let id = useSelector(state => state.id);
let password = useSelector(state => state.password);
const increase = () => {
 dispatch({ type:"INCREMENT" , payload {num:5} }); 
}
const login = () => {
  dispatch({ type:"LOGIN", payload: { id:"naa", password:"dd"} });
}


//reducer.js
//초기값에도 id, password 추가

switch(action.type) {
  case "INCREMENT":
    return{ ...state, count:state.count + action.payload.num};
  case "LOGIN":
    return{ ...state, id:action.payload.id, password:action.payload.password, };
  default:
  
}

 

- 리덕스 미들웨어 Redux middleware

-> 비동기 작업은 리덕스로 불가한 것을 해결하기 위해 리덕스 미들웨어  

 

리듀서로 가기 전 미들웨어에서 처리 

 

- redux thunk

- redux saga

 

redux thunk  : npm install redux-thunk

 

- redux toolkit

reducer.js 부분을 툴킷을 사용해서 수정

//기존의 reducer.js

let initalState = {
  productList:[],
  selectedItem:null,
};

function Reducer(state = initialState, action) {
  let { type, payload } = action;
  switch (type) {
    case "GET_PRODUCT_SUCCESS":
      return { ...state, productList: payload.data };
    case "GET_SINGLE_PRODUCT_SUCCESS":
      return { ...state, selectedItem: payload.data };
    default:
      return { ...state };
  }
}

export default Reducer;

 

redux toolkit으로 바꿔서 구현

//리덕스 툴킷 

import {createSlice} from redux-toolkit

let initialState = {
  productList:[],
  selectedItem :null,
};

const productSlice = createSlice({
  name :"product",
  initialState,
  reducers:{
    getAllProducts(state,action){
      state.productList = action.payload.data
    },
    getSingleProducts(state, action){
      state.selectedItem = action.payload.data
    },
  },
});

export default productSlice.reducer;

 

store.js 부분을 툴킷을 사용해서 수정

// 기존의 store.js 

import { createStore, applymiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";

let store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(thunk))
);

export default store;

//리덕스가 업데이트 하면서 createstore를 지원하지 않으려 함
//툴킷을 이용한 store
//configureStore 사용

import { createStore, applymiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";

import {configureStore} from "@reduxjs/toolkit"


const store = configureStore({
  reducer:{
    auth: authenticateReducer,
    product : productReducer,
  }
})

export default store;
//dispatch 하는 법
//dispatch 해야하는 컴포넌트에서 
import { productActions } from "../reducers/productReducer"

dispatch(productActions.getAllProducts()) 
//action 객체를 만들어 줄 필요없이 action의 함수 바로 호출
//payload 는 getAllProducts(date) 매개변수로 보내줌