지난번 글에서 Redux에 대해서 포스팅 했는데 제대로 이해가 되지 않아서 예제로 확인해보려고 한다.

(App.js 는 작성하지 않아도 있다고 가정하고 예제를 만들어 보려고 한다.

모든 컴포넌트는 src에 있음을 염두해두고 코드를 작성해보려고 한다.)

 

Reducer 부분

reducer/orderReducer/index.js

// Reducer 함수
// 초기값을 기본으로 할당

// state
// 기본값을 할당
// 초기에는 기본값이 사용된다.

const initialState = {
  order: ""
}

const reducer = (state = initialState, action) => {
  // state 초기에는 기본값으로 할당한 initialState가 할당되ㅏ고
  // 상태를 업데이트 이후에는 이전 상태값을 할당해준다.
  // reducer 꼭 반환 값이 있어야한다.
  
  const { type, payload } = action;
  switch (type){
    case "김치볶음밥":
      return { ...state, order: "김치볶음밥" }
    
    case "계란볶음밥":
      return { ...state, order: "계란볶음밥" }
      
    default:
      return state
  }
}

export default reducer

 

reducer/userReducer/index.js

(로그인 관련 리듀서는 해당 코드에 필요하지는 않다. combineReducers를 보여주기위한 예시로 적었으니 참고.)

const initialState = {
  user: null
}

const reducer = (state = initialState, action) => {
  // state 초기에는 기본값으로 할당한 initialState가 할당되고
  // 상태를 업데이트한 이후에는 이전 상태값을 할당해준다.
  // reducer 는 꼭 반환값이 있어야한다.
  const { type, payload } = action;
  switch (type) {
    case "LOGIN":
      return { ...state, user: { name: 'jaka' } }
    case "LOGOUT":
      return { ...state, user: null }
    default:
      return state;
  }
}

export default reducer;

 

reducer/index.js

( combineReducers : 리듀서를 하나로 합친다.)

import userReducer from './userReducer';
import orderReducer from './orderReducer';
import { combineReducers } from 'redux';

// 여러개의 리듀서를 하나로 합치자
export const reducer = combineReducers({
  userReducer,
  orderReducer
})

 

store/index.js.

createStore : 스토어를 생성한다.

applyMiddleware : 미들웨어를 추가하는 함수.

thunk : 액션크리에이터 함수를 만들어서 비동기 처리를 하기 위함)

import { createStore, applyMiddleware } from 'redux';
import { thunk } from 'redux-thunk';
import { reducer } from '../reducer';

// createStore : store 인스턴스 생성

// 사가와 thunk
// 미들웨어 추가
// thunk를 사용하는 이유는 미들웨어로 액션 크리에이터 함수를 만들어서 비동기 처리를 할 수 있다.

// applyMiddleware : 미들웨어를 추가하는 함수
export const store = createStore(reducer, applyMiddleware(thunk));

 

action/index.js  (axios 함수)

import axios from 'axios'
// 액션 크리에이터 함수

Export const getUserAction = (type) => {
  return async (dispatch, getState) => {
    const data = await axios.get('http://localhost:4000');
    setTimeout(() => {
      dispatch({ type, payload: data })
    }, 2000);
  }
}

 

components/Form.jsx

import { useSelector, useDispatch } from 'react-redux';

export const Form = () => {
  // store에 접근해서 전역상태를 참조
  // UseSelector : store의 상태를 참조할 수 있게 도와주는 hook
  // useSelector로 값을 참조하면 가져온 상태를 주시하게 된다.
  // 주시하고 있는 값이 변하면 해당 컴포넌트가 리렌더링
  // 매개변수로 콜백함수 전달.
  // 콜백함수에서 반환된 값을 주시한다.
  // 콜백함수의 매개변수로 현재 상태를 할당해준다.
  const order = useSelector(state => state.orderReducer.order);
  const dispatch = useDispatch();
  
  const handlerOrder = () => {
    if (e.target.innerText === '김치볶음밥 주문'){
      dispatch({ type: "김치볶음밥" })
      // 매개변수로 함수를 전달하면 액션 크리에이터 함수로 처리르 한다.
      dispatch(async (dispatch, getState) => {
      //  const payload = await.axios.get();
      //  dispatch({ type: '김치볶음밥', payload: {} })
      });
	  // dispatch(getUserAction('김치볶음밥');      
    } else if (e.target.innerText === "계란볶음밥 주문") {
      dispoatch({ type: '계란 볶음밥', payload: {}})
    }
  }
  
  return <>
    <h1>{order === "" ? "주문하시겠습니까?" : `${order} 나왔습니다.`}</h1>
    <button onClick={handlerOrder}>김치볶음밥 주문</button>
    <button onClick={handlerOrder}>계란볶음밥 주문</button>
  </>
}

+ Recent posts