Practice : Food App

2JE0·2022년 1월 26일
0

React

목록 보기
12/17
post-thumbnail

Modal 만들기

  • Modal.js 파일 안에서 Modal BackDrop 컴포넌트를 만든다.

  • 모달컴포넌트 안에 props.children을 넣어준다.

  • index.html의 최상위 태그를 만들어준다. (id=overlay)

  • createPortal을 사용한 코드는 다음과 같다.

//Modal.js
import React from "react";
import classes from "./Modal.module.css";
import reactDom from "react-dom";

const BackDrop = () => {
  return <div className={classes.backdrop}></div>;
};
const Modal = (props) => {
  const overlayPosition = document.getElementById("overlay");
  return (
    <>
      {reactDom.createPortal(<BackDrop />, overlayPosition)}
      {reactDom.createPortal(
        <div className={classes.modal}>{props.children}</div>,
        overlayPosition
      )}
    </>
  );
};

export default Modal;

Context API 사용

  • store 이라는 폴더를 만들고 cart-context.js 파일을 만든다.

  • cart-context는 공유할 변수와 함수를 담는 곳이다.

import React from "react";

const CartContext = React.createContext({
  item: [],
  totalAmount: 0,
  addItem: (item) => {},
  removeItem: (id) => {},
});

export default CartContext;
  • CartProvider 컴포넌트를 만든다.

  • cartContext는 업데이트 되는 값들을 집어넣는 곳이다. 나중에 동적으로 할당해주기 위해 더미 데이터를 집어넣는다.

  • value props로 업데이트 되는 값들을 집어넣어준다.

//CartProvider.js
import React from "react";
import CartContext from "./cart-context";

const CartProvider = (props) => {
  const addItemToCartHandler = (item) => {};
  const removeItemFromCartHandler = (item) => {};

  const cartContext = {
    item: [],
    totalAmount: 0,
    addItem: addItemToCartHandler,
    removeItem: removeItemFromCartHandler,
  };
  return (
    <CartContext.Provider value={cartContext}>
      {props.children}
    </CartContext.Provider>
  );
};

export default CartProvider;
  • 데이터를 사용하고 싶은 장소에서 import { useContext } from "react";
    import CartContext from "../../store/cart-context"; 두개를 import 해준다.

  • const ctx = useContext(CartContext); 로 변수를 사용한다.


Java Script reduce()

장바구니에 있는 모든 물건의 갯수를 세기 위해서 필요한 빌트인 함수

item 의 모든 요소를 돌면서 현재 있는 값curitem.amount를 더한 것을 리턴한다.

  const totalNumber = ctx.item.reduce((cur, item) => {
    return cur + item.amount;
  }, 0)

useRuducer 사용

  • import React, { useReducer } from "react"; 해준다.

  • 컴포넌트 안에 기본적인 useReducer 문을 적는다.

  const [cartState, dispatchCart] = useReducer(cartReducer, {
    defaultCartState,
  });
  • const defaultCartState = { item: [], totalAmount: 0 }; 디폴트 값이다.
  • 이전에 만들어뒀던 Context의 함수부분 addItemToCartHandlerremoveItemFromCartHandler에서 dispatchCart를 실행시킨다.
  const cartContext = {
    item: cartState.item,
    totalAmount: cartState.totalAmount,
    addItem: addItemToCartHandler,
    removeItem: removeItemFromCartHandler,
  };
  • 그러면 action으로 다음의 인자가 전달이 되는데 전달받은 곳에서 cartReducer 함수가 실행된다.
    하지만 이 함수는 컴포넌트의 바깥에 존재해야 한다.
  const addItemToCartHandler = (item) => {
    dispatchCart({
      type: "ADD",
      item: item,
    });
  };
  const removeItemFromCartHandler = (id) => {
    dispatchCart({ type: "REMOVE", id: id });
  };
  • concat이라는 자바스크립트 빌트인 함수를 사용했는데 push를 사용하지 않은 이유는 concat이 새로운 배열을 만들기 때문이다.(push는 수정함)
const cartReducer = (state, action) => {
  if (action.type === "ADD") {
    const newitems = state.item.concat(action.item);
    const newAmount =
      state.totalAmount + action.item.price * action.item.amount;
    return {
      item: newitems,
      totalAmount: newAmount,
    };
  } else if (action.type === "REMOVE") {
  }
  return defaultCartState;
};

useRef & forwardRef

커스텀 컴포넌트에서는 ref의 기능을 사용할 수 없다.
따라서 <INPUT>컴포넌트 안에 있는 <input> 에서 forwardRef를 사용해야 한다.

  • React.forwardRef 으로 감싸주고 <input>ref을 추가해준다.
import React from "react";
import classes from "./Input.module.css";

const Input = React.forwardRef((props, ref) => {
  return (
    <div className={classes.input}>
      <label htmlFor={props.id}>{props.label}</label>
      <input {...props.input} ref={ref} />
    </div>
  );
});

export default Input;
  • 상위 컴포넌트로 가서 useRefimport 해준다.

  • const amountData = useRef(); 선언후 amount.current.value로 사용한다.


에니메이션 추가하기

특정 조건 (Cart에 음식을 담을 때)에서 에니메이션을 추가하는 방법

  • useState를 사용해서 에니메이션을 진행할지 안할지에 대한 변수를 선언한다. const [isBump, setIsBump] = useState(false);

  • 클래스를 동적으로 추가한다. const bumpClasses = `${classes.button} ${isBump ? classes.bump : ""}`;

  • useEffect 와 구조분해 할당을 이용해서 클래스를 계속 추가했다가 빼준다.

const { item: newCtxItem } = ctx;
  useEffect(() => {
    if (newCtxItem.length < 1) return;

    setIsBump(true);
    const timer = setTimeout(() => {
      setIsBump(false);
    }, 300);
    return () => {
      clearTimeout(timer);
    };
  }, [newCtxItem]);

0개의 댓글

관련 채용 정보