[React.js] 리액트 최적화(useMemo, React.memo, useCallback)

2024. 3. 21. 16:45Web/React.js

useMemo란

"메모이제이션" 기법을 기반으로 불 필요한 연산을 최적화 하는 리액트 훅

Memoization: 기억해두기, 메모해두기 라는 뜻

동일한 연산이 필요해질때 마다 재연산을 통해 결과값을 가져오는것이 아닌

처음 연산이 이루어 질때 메모리 어딘가에 저장해두고 다음에 연산이 필요할때

저장된 값을 가져다 쓰는것 이다.

 

const { totalCount, doneCount, notDoneCount } = useMemo(() => {
    console.log("getAnalyzedData 호출");
    const totalCount = todos.length;
    const doneCount = todos.filter((todo) => todo.isDone).length;
    const notDoneCount = totalCount - doneCount;

    return {
      totalCount,
      doneCount,
      notDoneCount,
    };
  }, [todos]);

useMemo 문법

뎁스의 값이 변경되면 콜백 함수를 호출하여 코드가 다시 실행이 된다

 

React.memo란

리액트의 내장함수로

컴포넌트를 인수로 받아, 최적화된 컴포넌트로 만들어 반환

const MemoizedComponnent = memo(Component)

           ㄴ반환값 : 최적화된 컴포넌트         ㄴ 인수 : 컴포넌트

           Props를 기준으로 메모이제이션 됨

부모컴포넌트가 리렌더링 되도 자신이 받는 Props가 바뀌지않으면 자신은 리렌더링 되지 않도록

메모이제이션이 되기 때문에 불필요한 리렌더링을 방지함으로 자동으로 최적화가 된다.

 

import "./Header.css";
import { memo } from "react";

const Header = () => {
  return (
    <div className="Header">
      <h3>오늘은 📅</h3>
      <h1>{new Date().toDateString()}</h1>
    </div>
  );
};

const memoizdHeader = memo(Header);

export default memoizdHeader;

이렇게 사용을 하거나

import "./Header.css";
import { memo } from "react";

const Header = () => {
  return (
    <div className="Header">
      <h3>오늘은 📅</h3>
      <h1>{new Date().toDateString()}</h1>
    </div>
  );
};

export default memo(Header);

이렇게 단축해서 사용할 수도 있다.

 

import "./TodoItem.css";
import { memo } from "react";

const TodoItem = ({ id, isDone, content, date, onUpdate, onDelete }) => {
  const onChangCheckbox = () => {
    onUpdate(id);
  };

  const onClickDeleteButton = () => {
    onDelete(id);
  };

  return (
    <div className="TodoItem">
      <input
        onChange={onChangCheckbox}
        readOnly
        checked={isDone}
        type="checkbox"
      />
      <div className="content">{content}</div>
      <div className="date">{new Date(date).toLocaleDateString()}</div>
      <button onClick={onClickDeleteButton}>삭제</button>
    </div>
  );
};

export default memo(TodoItem, (precProps, nextProps) => {
  //반환값에 따라, Props가 바뀌었는지 안바뀌었는지 판단
  //true -> Props가 바뀌지 않음 -> 리렌더링X
  //false -> Props가 바뀜 -> 리렌더링 O

  if (precProps.id !== nextProps.id) return false;
  if (precProps.isDone !== nextProps.isDone) return false;
  if (precProps.content !== nextProps.content) return false;
  if (precProps.date !== nextProps.date) return false;

  return true;
});

memo함수는 객체의 주소값을 비교하기 때문에

값으로 비교를 하고싶다면 이런식으러 사용을 하면된다.

 

useCallback

함수를 메모이제이션 하는 훅으로

 

객체를 마운트 된이후에 컴포넌트가 리렌더링 될때 함수 재생성을 막고싶다면

useCallback을 사용해서 

  const onDelete = (targetId) => {
    dispatch({
      type: "DELETE",
      targetId: targetId,
    });
  };

const onDelete = useCallback((targetId)=>{
    dispatch({
      type: "DELETE",
      targetId: targetId,
    });
  },[])

이런식으로 바꿔주면 된다.

 

 

 

 

 

반응형

'Web > React.js' 카테고리의 다른 글

[React.js] React Page Routing, Link, useNavigate  (0) 2024.03.25
[React.js] React Context  (0) 2024.03.25
[React.js] useReducer  (0) 2024.03.20
[React.js] 라이프사이클(LifeCycle)  (0) 2024.03.15
[React.js] React Hooks  (0) 2024.03.13