udemy 강의 듣고 적어보는 리덕스를 적용하여 커머스 사이트 만들기.
지금까지 user 리듀서를 만들어서 user의 로그인 여부를 보였다면 이번에는 cart에 물건을 담을걸 드롭다운으로 보이게 하는 기능을 만든다.
일단, 컴포넌트로 cart-icon, cart-dropdown을 만들어서 cart-icon에는 아이콘을, cart-dropdown은 드롭다운을 어떻게 보일건지 구성하고 sass로 꾸민다.
홈페이지 상단 header에 들어갈 부분이라, header 컴포넌트에 넣는데, 이제부터 리덕스를 만들면된다.
리덕스 파일안에, cart라는 폴더를 만들고 action, reducer, types 을 만든다.
그리고 먼저 reducer로 가서 초기값을 설정하고, 초기값이 어떻게 바뀌면 어떻게 할건지 swtich 문으로 로직을짠다.
여기서는 TOGGLE_CART_HIDDEN이라고 상태를 정의했다. (헤더의 카드 아이콘이 눌렸을떄 토글되도록)
그리고나서 root-reducer에 담아서 하나의 리듀서로 만들면 리듀서 사용 준비 끝.
이제 만들어둔 컴포넌트들과 리듀서를 이으면된다.
카트를 눌렀을때 작동되는 방식이니, cart-icon 컴포넌트로 가서, 하단에 mapDispatchToProps 와 cartIcon을 연결시킨다.
mapDispatchToProps함수는 만들어둔 리듀서 action을 호출하고, 액션은 리듀서를 호출하는 방식이다.
리턴 값으로는 hidden : !state.hidden 인데 이 값을 cartIcon의 인자로 받아서 클릭 할때 상태를 변화하도록 만든다.
이제 이정보를 header로 가져가서 드롭다운 메뉴를 토글되었을때 보이도록 삼항 연산자로 묶으면된다.
const Header = ({ currentUser, hidden }) => (
<div className="header">
<Link className="logo-container" to="/">
<Logo className="logo" />
</Link>
<div className="options">
<Link className="option" to="/shop">
SHOP
</Link>
<Link className="option" to="/shop">
CONTACT
</Link>
{currentUser ? (
<div className="option" onClick={() => auth.signOut()}>
SIGN OUT
</div>
) : (
<Link className="option" to="/signin">
SIGN IN
</Link>
)}
<CartIcon />
{/* <Cart currentUser ={currentUser}/> */}
</div>
{hidden ? null : <Cart />}
</div>
);
// root- reducer 에 access있는 함수.
const mapStateToProps = ({ user: { currentUser }, cart: { hidden } }) => ({
currentUser,
hidden,
});
export default connect(mapStateToProps)(Header);
//값이 변경되었을때만 re-render됨.
header도 역시 connect으로 처리를 하고 mapStateToProps를 사용한다. 이때 헤더는 user의 상태와 cart의 상태 둘다 가지고 있어서 destructoring으로 처리한뒤 header의 인자로 보낸다.
출처
connect : 리덕스가 제공하는 connect 함수는 store가 업데이트 되었을때, 값을 읽을수 있게 함.
connect(mapStateToProps,mapDispatchToProps) 이렇게 2개의 인자를 받는데
mapStateToProps: 스토어의 상태가 변경되었을 때마다 호출, store의 모든 상태를 받고, 컴포넌트가 필요한 객체 리턴 (리랜더링됨 null 이나 생략시 스토어 변경시 리랜더링 안함)
mapDispatchToProps: 함수/ 객체 일수 있고 함수일경우, 컴포넌트가 생성되었을때 1번 호출되는데 dispatch를 인자로 받고, 액션에서 받아온 객체를 반환.
객체일 경우, 액션의 생성자가 되고 액션이 호출될때 props로 쓰임.
값이 변경되었을때 리랜더링.