728x90
반응형
목차
useReducer란?
리액트의 useReducer는 상태관리와 상태 업데이트를 다루는 리액트 훅 중 하나로
복잡한 로직의 상태관리를 하거나 여러 컴포넌트의 상태를 공유할 때 이용한다.
useState와 유사하나 더 구조적으로 꼭 사용해야 하는 것은 아니지만 필요할 때 선택적으로 이용할 수 있다.
간략한 용어 정리
- state -> 현재 상태
- dispatch -> 상태 변경 시 필요한 정보를 전달하는 함수
- reducer -> dispatch를 확인해서 state를 변경해 주는 함수
- initial state -> state에 전달할 초기값
예를 통해 알아보는 사용방법
1. dispatch 만들어 주기
shoppingCartreducer라는 상태 변경 함수를 첫번째 인자로 주고 두번째 인자로는 초기값을 전달해 준다.
// action에 전달될 함수와 초기값 설정
const [shoppingCartState, shoppingCartDispatch] = useReducer(
shoppingCartReducer,
{
items: [],
}
);
// 인수: 최신 state와 action(업데이트를 위한 정보를 가지고 있는 객체)
//reducer는 항상 최신 상태 반환한다.
function shoppingCartReducer(state, action) {
return state;
}
2. action에 전달될 함수 만들어 주기
action에 전달될 함수의 종류와 전달 인자를 setDispatch를 통해 설정해준다.
function handleAddItemToCart(id) {
shoppingCartDispatch({
//각각의 action을 구분하기 위함
type: "ADD_ITEM",
payload: id, //전달 인자 설정
});
// -> action 매개 변수로 전달
}
function handleUpdateCartItemQuantity(productId, amount) {
shoppingCartDispatch({
type: "UPDATE_ITEM",
payload: { productId, amount },
});
}
3. 리듀서 함수에서 분기시켜 최신 상태 반영하기
이런식으로 action.type을 if조건문으로 분기시켜 함수 타입별로 상태를 변경하고 최신상태를 반영할 수 있다.
인자를 쓰고 싶다면 action.payload와 같이 사용해 주면 된다.
function shoppingCartReducer(state, action) {
if (action.type === "ADD_ITEM") {
const updatedItems = [...state.items];
const existingCartItemIndex = updatedItems.findIndex(
(cartItem) => cartItem.id === action.payload
);
const existingCartItem = updatedItems[existingCartItemIndex];
if (existingCartItem) {
const updatedItem = {
...existingCartItem,
quantity: existingCartItem.quantity + 1,
};
updatedItems[existingCartItemIndex] = updatedItem;
} else {
const product = DUMMY_PRODUCTS.find(
(product) => product.id === action.payload
);
updatedItems.push({
id: action.payload,
name: product.title,
price: product.price,
quantity: 1,
});
return {
//데이터 손실이 없도록 지난번 상태 복사
...state,
items: updatedItems,
};
}
}
if (action.type === "UPDATE_ITEM") {
const updatedItems = [...state.items];
const updatedItemIndex = updatedItems.findIndex(
(item) => item.id === action.payload.productId
);
const updatedItem = {
...updatedItems[updatedItemIndex],
};
updatedItem.quantity += action.payload.amount;
if (updatedItem.quantity <= 0) {
updatedItems.splice(updatedItemIndex, 1);
} else {
updatedItems[updatedItemIndex] = updatedItem;
}
return {
...state,
items: updatedItems,
};
}
return state;
}
반응형
'코딩 정보 > React' 카테고리의 다른 글
[React] sideEffect가 무엇이고 useEffect에 대해 알아보자 (0) | 2024.07.19 |
---|---|
[React] 랜더링의 동작과 관련 개념을 자세히 알아보자 (1) | 2024.07.17 |
[React] context api를 이용해서 props drilling 막기 (0) | 2024.07.14 |
[React] useRef의 응용과 createPortal 에 대해 알아보자 (1) | 2024.07.04 |
[React] 디버깅의 방법을 예를 통해 알아보자 (0) | 2024.06.30 |