Skip to content

리액트 렌더링 최적화

yejineee edited this page Nov 11, 2020 · 1 revision
  • ✍️ writer: 양예진
  • 📆 date: 2020.11.11

📌 학습목표

  • 성능 최적화를 할 때 필요한 useMemo, useCallback, React.Memo에 대해 알아본다.

성능 최적화가 필요한 이유

  • 리액트 컴포넌트는 기본적으로 부모 컴포넌트가 리렌더링되면 자식 컴포넌트 또한 리렌더링 된다.

    바뀐 내용이 없을지라도 리렌더링된다. 컴포넌트 최적화를 하면 기존의 내용을 그대로 사용할 수 있다.

📌 useMemo

언제 useMemo를 사용하는가

  • 성능 최적화를 위하여 useMemo라는 훅을 사용하여 연산된 값을 재사용한다.
  • useMemo는 특정 결과값을 재사용할 때 사용한다.

useMemo

  • 첫 번째 파라미터: 어떻게 연산할지 정의하는 함수
  • 두 번째 파라미터 : deps 배열을 넣어준다.

deps안에 있는 내용이 바뀌면, 함수를 호출하여 값을 연산하고, 내용이 바뀌지 않는다면 이전에 연산한 값을 재사용하게 된다.

const count = useMemo(() => countActiveUsers(users), [users]);

📌 useCallback

언제 useCallback을 사용하는가

  • useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용한다.

useCallback이 필요한 이유

  • 함수를 선언하는 것 자체는 메모리도, CPU도 리소스를 많이 차지하는 작업은 아니다. 따라서 함수를 선언한다고 해서 그 자체만으로 큰 부하가 생기진 않지만, 한 번 만든 함수를 필요할 때만 새로 만들고 재사용하는 것은 여전히 중요하다.

    그 이유는, 컴포넌트에서 props 가 바뀌지 않았으면 Virtual DOM에서 컴포넌트 결과물을 재사용하는 최적화를 한다. 이 작업을 하려면 함수 재사용하는 것이 필수적이다.

useCallback

  • 첫 번째 인자: 사용할 함수

  • 두 번째 인자: 함수 안에서 사용하는 상태, props의 배열

    const onCreate = useCallback(() => {
        const user = {
          id: nextId.current,
          username,
          email
        };
        setUsers(users.concat(user));
    
        setInputs({
          username: '',
          email: ''
        });
        nextId.current += 1;
      }, [users, username, email]);

📌 React.Memo

언제 React.Memo를 사용하는가

  • 컴포넌트의 props가 안바뀌었을 경우, 컴포넌트 리렌더링을 방지해준다.

  • 컴포넌트에서 리렌더링이 필요한 상황에서만 리렌더링을 하도록 설정할 수 있다.

  • 렌더링 최적화하지 않을 component에 React.memo를 사용하면, 불필요한 props만 비교하게 된다.

    따라서 실제로 리렌더링을 방지할 수 있는 상황에서만 사용해야 한다.

React.memo

  • 최적화를 시켜줄 컴포넌트를 React.memo로 감싸준다.
function CreateUser({ username, email, onChange, onCreate }) {
  return (
    <div>
      <input
        name="username"
        placeholder="계정명"
        onChange={onChange}
        value={username}
      />
			...
      <button onClick={onCreate}>등록</button>
    </div>
  );
}
export default React.memo(CreateUser);

📌 함수형 업데이트

  • 콜백 함수의 파라미터에서 가장 최근의 state를 참조하게한다.

  • deps로 의존하는 값으로 state를 받아야할 때, 함수형 업데이트를 하여 콜백의 인자로 state를 준다.

    이렇게 하면, deps에 State를 넣지 않아도 된다. ⇒ state가 바뀔 때, 리렌더링되지 않는다!

setState(prevState => prevState + 1);
// 함수형 업데이트 적용 안했을 시, deps에 state를 넣어야 한다.
const onToggle = useCallback(id => {
    setUsers(
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  }, [users]);

// 함수형 업데이트
const onToggle = useCallback(id => {
    setUsers(users =>
      users.map(user =>
        user.id === id ? { ...user, active: !user.active } : user
      )
    );
  }, []);
  • Reference

https://react.vlpt.us/basic/19-React.memo.html

Clone this wiki locally