오늘 하루종일 리덕스 공부를 했는데,
천천히 모르는 부분을 계속 돌려보면서 보니
예전에 봤을 때 감도 못잡았던 부분을 알아낼 수 있었다!
(회사에서 해서 집중 더 잘됨ㅋㅋㅋㅎㅎ)
아무튼 리덕스가 뭔지는 오전에 올렸으니 어떻게 사용하는지에 대해 포스팅 해보겠다.
//리덕스 툴킷을 사용하지 않고 만드는 방법
//if문 대신 switch문을 사용해도 된다.
import { createStore } from 'redux';
const initialState = { counter: 0, showCounter: true };
const counterReducer = (state = initialState, action) => {
if (action.type === 'increment') {
return { counter: state.counter + 1, showCounter: state.showCounter };
}
//동적으로 변경 가능한 리듀서
if (action.type === 'increase') {
return {
counter: state.counter + action.amount,
showCounter: state.showCounter,
};
}
if (action.type === 'decrement') {
return { counter: state.counter - 1, showCounter: state.showCounter };
}
if (action.type === 'toggle') {
return { showCounter: !state.showCounter, counter: state.counter };
}
return state;
};
//리액트 툴킷으로 리듀서를 만드는 방법
//createSlice를 임포트한다.
//자동으로 값이 복사되고 원본이 바뀌지 않아서 값을 얼마든지 바꿀 수 있다.
//모든 값을 작성하지 않아도 알아서 작성해준다.
import { createSlice } from '@reduxjs/toolkit';
const cartSlice = createSlice({
name: 'cart',
initialState: {
items: [],
totalQuantity: 0,
},
reducers: {
addItemToCart(state, action) {
const newItem = action.payload;
const existingItem = state.items.find(
item => item.id === newItem.id
);
state.totalQuantity++;
if (!existingItem) {
state.items.push({
id: newItem.id,
price: newItem.price,
quantity: 1,
totalPrice: newItem.price,
name: newItem.title,
});
} else {
existingItem.quantity++;
existingItem.totalPrice =
existingItem.totalPrice + newItem.price;
}
},
removeItemFromCart(state, action) {
//action.payload로 매개변수를 받아올 수 있다.
const id = action.payload;
const existingItem = state.items.find(item => item.id === id);
state.totalQuantity--;
if (existingItem.quantity === 1) {
state.items = state.items.filter(item => item.id !== id);
} else {
existingItem.quantity--;
}
},
},
});
export const cartActions = cartSlice.actions;
export default cartSlice;
//store/index.js
import { configureStore } from '@reduxjs/toolkit';
import uiSlice from './ui-slice';
import cartSlice from './cart-slice';
const store = configureStore({
reducer: { ui: uiSlice.reducer, cart: cartSlice.reducer },
});
export default store;
//index.js
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import './index.css';
import App from './App';
import store from './store/index';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
//provider를 임포트해서 스토어를 넣어주면 된다.
<Provider store={store}>
<App />
</Provider>
);
//장바구니에 아이템을 담는 코드
import Card from '../UI/Card';
import classes from './ProductItem.module.css';
import { useDispatch } from 'react-redux';
import { cartActions } from '../../store/cart-slice';
const ProductItem = props => {
const { title, price, description, id } = props;
const dispatch = useDispatch();
const addToCartHandler = () => {
//카트 아이템을 저장해준다.
dispatch(
cartActions.addItemToCart({
id,
title,
price,
})
);
};
return (
<li className={classes.item}>
<Card>
<header>
<h3>{title}</h3>
<div className={classes.price}>${price.toFixed(2)}</div>
</header>
<p>{description}</p>
<div className={classes.actions}>
//디스패치를 온클릭에 할당
<button onClick={addToCartHandler}>Add to Cart</button>
</div>
</Card>
</li>
);
};
export default ProductItem;
import Cart from './components/Cart/Cart';
import Layout from './components/Layout/Layout';
import Products from './components/Shop/Products';
import { useSelector } from 'react-redux';
function App() {
//state로 리듀서의 이름에 접근하여 저장된 값에 접근한다.
const showCart = useSelector(state => state.ui.cartIsVisible);
return (
<Layout>
{showCart && <Cart />}
<Products />
</Layout>
);
}
export default App;