Memoization, 반응형 웹

SongNoin·2021년 10월 24일
0
post-thumbnail

Memoization

  • setState 함수를 사용하게 되면, 화면 전체가 다시 렌더가 되면서 state와 여러개의 함수들을 다시 그려내게 된다.

  • 그런데 onChange 이벤트로 setState 함수를 실행하게 되면 문자 하나하나 변경할때마다 컴포넌트가 다시 렌더가 되고 이과정에서 여러개의 state와 함수들이 계속해서 재생성된다.

  • 컴포넌트의 크기가 매우 크거나 함수의 로직이 매우 길다면 set 함수로 인해 처음부터 다시 그려내는 과정이 불필요하다가 느껴지게 된다.

  • 메모이제이션은 특정 연산이나 특정 함수의 값을 기억해 놓은후 State의 변화로 컴포넌트의 재렌더하더라도 재생성이 아니라 기존에 저장된 값을 그대로 사용할 수 있게 해준다.

  • 메모이제이션 기능을 사용함으로서 컴포넌트의 불필요한 재렌더링을 줄여 좀 더 빠른 컴포넌트 렌더링을 유도할수 있다.

💻 코드적용

container.jsx

  • useMemoreact의 기능으로
    연산된 결과를 담는 변수의 값을 저장해준다.
    useMemo(() => 적용할 연산 함수, [ 적용할 변수 ])
    적용할 변수가 변경되었을 때만 메모이제이션 값만 다시 계산한다.

  • useCallback은 함수를 메모이제이션 해준다.
    useCallback(함수 로직, [ 의존성 배열 ])
    useCallback으로 메모이제이션한 함수는 재렌더링되지않아 렌더효율성을 올릴 수 있다.

import { useMemo, useCallback, useState } from "react";
...
  • 다음의 함수들을 이용하면 메모이제이션에 대해 이해할 수 있다.

  • onClickCountLetonClick함수는 콘솔창에서는 숫자가 올라가지만 화면상에는 숫자가 0에서 올라가지 않는다.

  • onClickCountStateonClick함수는 콘솔창에서도, 화면에서도 숫자가 올라간다.

  • 전자는 렌더링이 되고 있고 후자는 렌더링이 되고 있음을 의미한다.
export default function MemoizationContainerPage() {
  console.log("컨테이너가 렌더링 되었습니다!");
  let countLet = 0; // let 으로 선언했으면 컴포넌트가 다시 그려지지 않기 때문에 올라가지 않는다.
  const [countState, setCountState] = useState(0);
  // useState의 값이 바뀔때는 컴포넌트가 다시 렌더링 된다.
  // 자식도 다시 렌더링된다(부모는 되지않는다)
  const randomValue = useMemo(() => Math.random(), []); 
  // useMemo를 사용하면 기록된다. // useMemo는 함수도 기억가능!
  console.log(randomValue);
  const onClickCountLet = useCallback(() => {
    console.log(countLet + 1);
    countLet = countLet + 1;
  }, []);
  const onClickCountState = useCallback(() => {
    // console.log(countState + 1);
    setCountState((prev) => prev + 1);
  }, []);
  return (
    <>
      <div>카운트(let) : {countLet} </div>
      <button onClick={onClickCountLet}>카운트(let) +1</button>
      <div>카운트(state) : {countState}</div>
      <button onClick={onClickCountState}>카운트(state) +1</button>
      <MemoizationPresenterPage countState={countState} />
    </>
  );
}

presenter.tsx

  • memo는 컴포넌트를 메모이제이션 하는 기능이다.
    memo로 감싸진 컴포넌트의 결과를 저장시킨 후
    새로 렌더되는 결과가 저장된 결과와 같다면 해당 컴포넌트를 재렌더 하지 않게 된다.

  • memo로 적용된 컴포넌트는 상위 컴포넌트가 재렌더가 되더라도 넘어오는
    props의 값이 동일 하다면 컴포넌트를 재랜더하지 않게 된다.

import { memo } from "react"; // 리액트의 기능
function MemoizationPresenterPage(props) {
  console.log("프리젠터가 렌더링 되었습니다!");
  return (
    <>
      <div>=============================</div>
      <div>이것은 프리젠터입니다!!!</div>
      <div>=============================</div>
    </>
  );
}
export default memo(MemoizationPresenterPage);
// memo기능을 사용하면 재 렌더링 되지 않는다 (주로 속도,성능 차이를 위해서)
// 메모를 했다해도 바뀌는 props가 있다면 재 렌더링 된다.

반응형 웹 (Reponsive-media)

  • 모바일 환경에서 웹 접속이 보편화되고 자연스러워지면서 반응형 웹을 적용한 웹사이트들이 많아졌다.

  • 놀랍게도 이는 사이즈구간별로 각각의 다른 CSS코드가 존재 하는 것이었다.

  • 보통 모바일, 태블릿, 웹 세가지 구간으로 적용시킨다.

💻 코드적용하기

index.tsx

  • @media{ } 부분이 중요하다. 미디어쿼리 라고 한다.

import styled from "@emotion/styled";
import { breakPoints } from "../../src/commons/styles/media";
const Wrapper = styled.div`
  width: 1000px;
  height: 1000px;
  background-color: #cd5c5c;
  //* 미디어 쿼리
  @media ${breakPoints.tablet} {
    // 화면이 1199px 이하로 작아진다면 아래의 css가 적용된다.
    width: 500px;
    // 넓이는 보통 핸드폰 사이즈가 다양하기 때문에 % 를 준다.
    height: 500px;
    // 높이는 같이 커졌다 작아졌다하기 애매하기 때문에 고정한다.
    background-color: #4444c5;
  }
  @media ${breakPoints.mobile} {
    // 화면이 767px 이하로 작아진다면 아래의 css가 적용된다.
    width: 100px;
    height: 100px;
    background-color: #81d8b1;
    /* display: none; */ // 작아지면 안보이게끔 하게도 할수있다.
  }
`;
export default function ResponsiveMediaPage() {
  return (
    <>
      <Wrapper>상자</Wrapper>
    </>
  );
}

media.ts

  • 구간은 여러 페이지에서 적용할 수 있게 따로 컴포넌트화하는 것이 편하다.
export const breakPoints = {
  tablet: "(min-width : 768px) and (max-width: 1199px)",
  // 화면이 1199px 이하로 작아진다면 태블릿의 css가 적용된다.
  mobile: "(max-width : 767px)",
  // 화면이 767px 이하로 작아진다면 모바일의 css가 적용된다.
};

0개의 댓글