[React] 리렌더링

블루·2022년 11월 1일
0

리렌더링이 발생하는 상황

최초 렌더링이 끝난 이후, 컴포넌트의 State가 바뀌면 해당 컴포넌트와 그의 자식 컴포넌트는 리렌더링됩니다.


리렌더링 사이클

  • Rerendering -> DOM update -> useLayoutEffect -> useEffect

리렌더링 확인 방법

  • useEffect의 두번째 인자인 의존성 배열을 생략할 경우, 컴포넌트가 리렌더링될 때마다 실행됩니다.
useEffect(()=>{
  // logic
})

특정 state의 변화 확인 방법

  • 리렌더링되더라도 우선 Virtual DOM을 생성하고 이전 DOM과 비교하는 과정을 거쳐 변화된 부분만 바꿔주기 때문에 컴포넌트의 변화가 없더라도 리렌더링이 일어날 수 있습니다.
  • state의 변화가 있는지 확인하기 위하여 useEffect의 의존성 배열에 관찰하려는 props나 state를 넣어주면 의존성 배열에 넣어준 값이 바뀔 때마다 실행됩니다.
useEffect(()=>{
  	// logic
},[state, props])

리렌더링 최적화 방법

1. 리액트 컴포넌트가 렌더링 결과물을 지난번과 정확히 동일한 참조를 반환한다면, 리액트는 해당 하위 컴포넌트를 렌더링하는 것을 건너뜁니다.

import React, { ReactElement, useEffect, useState } from 'react';

const Parent = ({ children }: { children: ReactElement }) => {
  const [counter, setCounter] = useState(0);

  useEffect(() => {
    console.log('parent');
  });

  return (
    <div>
      <button onClick={() => setCounter((counter) => counter + 1)}>Count: {counter}</button>
      {children}
    </div>
  );
};

const Child = () => {
  useEffect(() => {
    console.log('child');
  });
  return <div>Hello</div>;
};

function App() {
  return (
    <Parent>
      <Child />
    </Parent>
  );
}

export default App;
import React, {  useEffect, useMemo, useState } from 'react';

const Child = () => {
  useEffect(()=>{
    console.log('child')
  })
  return (
    <div>Hello</div>
  )
}



function App() {
  const [counter1, setCounter1] = useState(0)
  const [counter2, setCounter2] = useState(0)

  useEffect(()=>{
    console.log('parent')
  })

  const memoizedElement = useMemo(()=>{
    return <Child/>
  // eslint-disable-next-line react-hooks/exhaustive-deps
  },[counter1])

  return (
    <div>
      <button onClick={()=> setCounter1(counter => counter+1)}>Counter 1: {counter1}</button>
      <button onClick={()=> setCounter2(counter => counter+1)}>Counter 2: {counter2}</button>
      {memoizedElement}
    </div>
  );
}

export default App;

2. React.Memo 사용

  • React.Memo로 감싼 컴포넌트는 변경된 props가 없으면 리렌더링이 발생하지 않습니다.
import React, { useCallback, useEffect, useState } from 'react';

const Child = React.memo(({ onClick }: any) => {
  useEffect(() => {
    console.log('child');
  });
  return <button onClick={onClick}>Counter 1</button>;
});

function App() {
  const [counter1, setCounter1] = useState(0);

  useEffect(() => {
    console.log('parent');
  });

  const onClick = useCallback(() => {
    setCounter1((counter1) => counter1 + 1);
  }, []);

  return (
    <div>
      <Child onClick={onClick} />
      <p>{counter1}</p>
    </div>
  );
}

export default App;

3. useMemo, useCallback을 이용한 props 참조 최적화




참고자료

profile
개발 일지를 작성합니다

0개의 댓글