본문 바로가기

React

useContext

useContext 사용법을 코드와 함께 정리해보도록 하겠습니다.

 

해당 로직은 장바구니를 클릭했을 때 modal이 나타났다 사라지는 기능을 담은 로직입니다.

 

app.js

모달 State의 기본값을 false로 설정하고 장바구닌 버튼을 클릭하면 true로 변경됨과 동시에 모달이 나타나게 설정하기 위해

 

Cart 컴포넌트에 props로 State 업데이트 함수를 전달해주었습니다.

 

Cart 컴포넌트에서는 전달받은 props로 닫기 버튼을 누르면 State를 false로 변경하여 모달이 사라기게 할 것입니다.

 

Header 컴포넌트에서는 전달 받은 props로 장바구니 버튼을 클릭하면 State를 true로 업데이트시켜 모달이 나타나게 됩니다.

 

Header.js

Header 컴포넌트는 전달 받은 props(모달 State 업데이트 함수)를 다시 HeaderCartButton 컴포넌트로 전달합니다.

 

HeaderCartButton.js

HeaderCartButton 컴포넌트에서는 전달 받은 props(모달 State 업데이트 함수)를 이용하여 버튼이 클릭됐을 때 State를 true로 업데이트 해줍니다.

 

Cart.js

Cart 컴포넌트에서는 전달 받은 props(모달 State 업데이트 함수)를 이용하여 닫기 버튼이 클릭됐을 때 State를 false로 업데이트 해줍니다.

 

 

App 컴포넌트에서 Cart 컴포넌트로 props를 전달할 때는 중간에 거치는 컴포넌트 없이 바로 사용하였습니다.

 

하지만 Header 컴포넌트에 props를 전달하고 HeaderCartButton으로 다시 재 전달하는 부분에서 

 

Header 컴포넌트는 해당 props를 사용하지 않음에도 불구하고 하위 컴포넌트인 HeaderCartButton 컴포넌트에 props를 전달하기 위해 전달을 받고 다시 재 전달을 해주어야 했습니다.

 

이때 useContext를 사용하면 해당 데이터를 전역적으로 사용할 수 있기 때문에 효율적으로 State를 전달할 수 있게됩니다.

 

 

cartModal-context.js

우선  cartModal-context.js 파일을 별도로 만들어 아래의 코드를 작성해주었습니다.

 

import React, { useState } from "react";

const CartModalContext = React.createContext({
  cartIsShown: false,
  onShowCart: () => {},
  onHideCart: () => {},
});

export const CartModalContextProvider = (props) => {
  const [cartIsShown, setCartIsShown] = useState(false);

  const showCartHandler = () => {
    setCartIsShown(true);
  };

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

  return (
    <CartModalContext.Provider
      value={{
        cartIsShown: cartIsShown,
        onShowCart: showCartHandler,
        onHideCart: hideCartHanler,
      }}
    >
      {props.children}
    </CartModalContext.Provider>
  );
};

export default CartModalContext;

 

 

 

index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <CartModalContextProvider>
    <App />
  </CartModalContextProvider>
);

사용하려는 곳 상위에서 만든 Context를 묶어줘야하기 때문에 index.js에서 App 컴포넌트를 감싸 주었습니다.

 

App.js
function App() {
  const { cartIsShown } = useContext(CartModalContext);

  return (
    <React.Fragment>
      {/* modal */}
      {cartIsShown && <Cart />}

      <Header />

      <main>
        <Meals />
      </main>
    </React.Fragment>
  );
}

export default App;

App 컴포넌트에서는 cartIsShown State가 false인지 아닌지만 필요하기 때문에 객체 비구조화를 통해 cartIsShown만 가져왔습니다.

 

HeaderCartButton.js
const HeaderCartButton = (props) => {
  const { onShowCart } = useContext(CartModalContext);
  return (
    <button className={classes.button} onClick={onShowCart}>
      <span className={classes.icon}>
        <CartIcon />
      </span>
      <span>장바구니</span>
      <span className={classes.badge}>3</span>
    </button>
  );
};

export default HeaderCartButton;

HeaderCartButton 컴포넌트도 동일한 방법으로 onShowCart 함수만 가져와서 사용하였습니다.

 

Cart.js
const Cart = (props) => {
  const { onHideCart } = useContext(CartModalContext);
  return (
    <Modal>
      {cartItems}
      <div className={classes.total}>
        <span>총 금액</span>
        <span>35.62</span>
      </div>
      <div className={classes.actions}>
        <button className={classes["button--alt"]} onClick={onHideCart}>
          Close
        </button>
        <button className={classes.button}>Order</button>
      </div>
    </Modal>
  );
};

export default Cart;

Cart 컴포넌트도 동일한 방법으로 필요한 함수만 가져와 사용하였습니다.

'React' 카테고리의 다른 글

useEffect  (0) 2022.10.14
Memoization(React.memo, useMemo, useCallback)  (2) 2022.10.11
Hook 사용 규칙  (0) 2022.10.08
useEffect 1 (로그인 / 로그아웃)  (0) 2022.10.03
React Portal 사용법  (0) 2022.10.03