온라인 강의/React 완벽 가이드 [Udemy]

150. 카트 및 모달 State 관리

유호야 2023. 6. 15. 07:13
반응형

장바구니를 클릭하면 리스트 Modal 창이 뜨고 close 버튼이나 모달 바깥 창을 클릭했을 때 꺼지도록 코드를 작성했다. 

중간에 왜 모달 창이 안 뜨나 했더니

Cart.js에서 map()를 사용할 때 key 값을 입력해주지 않아서 발생한 오류였다

 

Modal.js

import { Fragment } from 'react';
import ReactDOM from 'react-dom';

import classes from './Modal.module.css';

const Backdrop = props => {
  return <div className={classes.backdrop} onClick={props.onClose} />
};
const ModalOverlay = props => {
  return <div className={classes.modal}>
    <div className={classes.content}>{props.children}</div>
  </div>
};

const portalElement = document.getElementById('overlays');

const Modal = props => {
  return <Fragment>
    {ReactDOM.createPortal(<Backdrop onClose={props.onClose} />, portalElement)}
    {ReactDOM.createPortal(<ModalOverlay>{props.children}</ModalOverlay>, portalElement)}
  </Fragment>
};

export default Modal;

 

 

Cart.js

import classes from './Cart.module.css';
import Modal from '../UI/Modal';
const Cart = props => {
  const cartItems = (
    <ul className={classes['cart-items']}>
      {[
        { id: 'c1', name: 'Sushi', amount: 2, price: 12.99 }
      ].map((item) => <li key={item.id}>{item.name}</li>)}
    </ul>
  )
  return <Modal onClose={props.onClose}>
    {cartItems}
    <div className={classes.total}>
      <span>Total Amount</span>
      <span>30.33</span>
    </div>
    <div className={classes.actions}>
      <button className={classes['button-alt']} onClick={props.onClose}>close</button>
      <button className={classes.button}>add</button>
    </div>
  </Modal>
}

export default Cart;

 

App.js

import React, { useState } from 'react';
import Header from './components/Layout/Header';
import Meals from './components/Meals/Meals';
import Cart from './components/Cart/Cart';

function App() {
  const [cartIsShown, setCartIsShown] = useState(false);
  const showCartHandler = () => {
    setCartIsShown(true);
  };

  const hideCartHandler = () => {
    setCartIsShown(false);
  }

  return (
    <React.Fragment>
      <Header onShowCart={showCartHandler} />
      {cartIsShown && <Cart onClose={hideCartHandler} />}
      <main>
        <Meals />
      </main>
    </React.Fragment>
  );
}


export default App;

 

Header.js

import React from 'react';
import mealsImg from '../../assets/meals.jpg';
import HeaderCartButton from './HeaderCartButton';
import styles from './Header.module.css';

const Header = (props) => {
  return <React.Fragment>
    <header className={styles.header}>
      <h1>ReactMeals</h1>
      <HeaderCartButton onClick={props.onShowCart} />
    </header>
    <div className={styles['main-image']}>
      <img src={mealsImg} alt="A table full of delicious food!" />
    </div>
  </React.Fragment>
}

export default Header;
반응형