지난번 글에서 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>
</>
}
'React' 카테고리의 다른 글
[React] Vite에 대해서 (1) | 2025.01.29 |
---|---|
[React] Redux (store를 전역 상태로 관리) (1) | 2024.10.20 |
[React] useReducer로 상태를 다뤄보자 (0) | 2024.10.18 |
[React] useRef (리액트에서 DOM에 접근하기) (0) | 2024.10.17 |
[React] Context API 란? (useContext, 전역상태 관리) (1) | 2024.10.13 |