220907 TIL

CoderS·2022년 9월 7일
0

TIL DAY 211

오늘 배운 일

✔️ React 훅 더 공부하기

유튜버 코딩애플님과 별코딩님의 강의들을 보고 요약한 나의 일지

Part 1 ) useTransition & useDeferredValue

useTransition

  • 리액트 18버전부터 등장한 useTransition 은 느린 컴포넌트의 동작들을 빠르게 작동시키는 훅이다.

예 )

App.js

import { useState, useTransition, useDeferredValue } from "react";

let a = new Array(10000).fill(0);

export default function App() {
  let [name, setName] = useState("");
  let [isPending, startTransition] = useTransition();
  let state = useDeferredValue(name);

  return (
    <div className="App">
      <input
        onChange={(e) => {
          startTransition(() => {
            setName(e.target.value);
          });
        }}
      />
      {isPending
        ? "로딩중"
        : a.map(() => {
            return <div>{state}</div>;
          })}
    </div>
  );
}

위의 코드는 input 이 작성할 때, 배열이 10000번 동작시키는 코드이다.
정확히는 완성된 코드이다.

아까 말했듯이 useTransition 은 state 의 변경 함수에 성능 저하가 일으키면 사용한다.

모양은 useState 와 비슷한데, 첫 번째 인자로는 isPending, 그리고 두 번째는 startTransition 라는 인자를 받는다.

isPending 은 startTransition 이 처리중일 때 true 로 변한다.
startTransition 은 함수이고 콜백을 사용해서 동작할 코드를 늦게 처리하게 해준다.

늦게 처리한다는 의미는 렌더링이 될 때, 먼저 실행되는게 있고 그 후에는 useTransition 의 사용한 코드가 작동한다.

그리고 useDeferredValue 는 useTransition 을 써도 느리다고 생각되면, 사용하는 기능이다.

작동방식은 안에 있는 state 에 변동사항이 생기면 늦게 처리해준다.

Part 2 ) React.memo & useMemo

예 )

App.js

import { useMemo, useState } from "react";
import Child from "./Child";

export default function App() {
  const [parentAge, setParentAge] = useState(0);

  const incrementParentAge = () => {
    setParentAge(parentAge + 1);
  };

  console.log("부모 컴포넌트가 렌더링 되었어요");

  const name = useMemo(() => {
    return {
      lastName: "홍",
      firstName: "길동"
    };
  }, []);
  return (
    <div style={{ border: "2px solid navy", padding: "10px" }}>
      <h1>💑부모</h1>
      <p>age : {parentAge}</p>
      <button onClick={incrementParentAge}>부모 나이 증가</button>
      <Child name={name} />
    </div>
  );
}

Child.js

import { memo } from "react";

function Child({ name }) {
  console.log("자녀 컴포넌트도 렌더링 되었네요");
  return (
    <div style={{ border: "4px solid powderblue", padding: "35px" }}>
      <h3>👶자녀</h3>
      <p>성: {name.lastName}</p>
      <p>이름: {name.firstName}</p>
    </div>
  );
}

export default memo(Child);

이번에는 React.memo 와 useMemo 를 활용한 코딩이다.

React.memo 는 useMemo, useCallback 와 마찬가지로, 컴포넌트를 최적화 시키는 기법이다.

React.memo를 통해 불필요한 렌더링을 방지해서 앱의 성능을 향상시킬 수 있다.

React.memo 는 리액트에서 제공하는 고차 컴포넌트(HOC)이다.

최적화가 된 컴포넌트는 렌더링되어야 할 상황일 때마다, prop check 를 통해 자신이 받는 props 에 변화가 있는 없는지 확인한다.

Props 에 변화가 있다면?

  • 렌더링을 하게 된다.

Props 에 변화가 없다면?

  • 새로 렌더링을 하는게 아니라 기존에 렌더링이 된 내용을 재사용한다.

React.memo 에서 memo 는 Memoization 을 뜻한다.

Memoization

Memoization 이란 이미 계산한 값을 메모리 상에 저장하고 필요할 때마다 꺼내서 재사용하는 기법이다.

하지만 완벽하게 보여도, 무분별한 사용은 독이 될 수 있다.

그 이유는 컴포넌트를 메모이징 할 때 렌더링 된 결과를 어딘가에 저장해야 하기 때문에 메모리를 추가적으로 소비한다.

React memo 써야 할 때

  1. 컴포넌트가 같은 Props 로 자주 렌더링 될 때
  2. 컴포넌트가 렌더링이 될때마다 복잡한 로직을 처리해야할 때

React.memo 는 오직 Props 변화에만 의존하는 최적화 방법이다. (중요!)

만약 컴포넌트가 useState, useReducer 그리고 useContext 와 같은 상태 관련 훅을 사용한다면, props 에 변화가 없더라도 여전히 state 와 context 가 변할때마다 다시 렌더링이 된다.

주의할 점!

  • 자바스크립트에서 객체는 문자열과 숫자형 같은 원시 타입들과 달리 변수 안에 그대로 저장되는게 아니라, 해당 객체가 저장되어있는 메모리의 주소가 변수안에 저장된다. (ex: #1111)

  • 렌더링이 될 때마다, 객체 안에 있는 메모리의 주소가 바뀐다!

Part 3 ) React.memo & useCallback

예 )

App.js

import { useState, useCallback } from "react";
import Child from "./Child";

export default function App() {
  const [parentAge, setParentAge] = useState(0);

  const incrementParentAge = () => {
    setParentAge(parentAge + 1);
  };

  console.log("부모 컴포넌트가 렌더링 되었어요");

  const tellMe = useCallback(() => {
    console.log("길동아 사랑해 ❤");
  }, []);

  return (
    <div style={{ border: "2px solid navy", padding: "10px" }}>
      <h1>💑부모</h1>
      <p>age : {parentAge}</p>
      <button onClick={incrementParentAge}>부모 나이 증가</button>
      <Child name={"홍길동"} tellMe={tellMe} />
    </div>
  );
}

Child.js

import { memo } from "react";

function Child({ name, tellMe }) {
  console.log("자녀 컴포넌트도 렌더링 되었네요");
  return (
    <div style={{ border: "4px solid powderblue", padding: "35px" }}>
      <h3>👶자녀</h3>
      <p>이름: {name}</p>
      <button onClick={tellMe}>엄마 나 사랑해?</button>
    </div>
  );
}

export default memo(Child);

이번에는 React.memo 와 useCallback 훅을 활용한 코딩이다.
위에 코드는 2번째에서 본 코딩과 흡사하지만, 이번에는 함수를 메모이징하는 것이다!

useCallback 은 어떠한 함수를 메모이징하기 위해서 사용한다.

반면에, useMemo 는...

useMemo 는 어떠한 값을 메모이징하기 위해서 사용한다.

주의할 점!

  • 함수도 마찬가지로 객체와 비슷하게 렌더링이 되면 새로운 메모리 주소가 저장된다.
profile
하루를 의미있게 살자!

0개의 댓글