개발공작소
article thumbnail
728x90

 

 

 

리액트에서 컴포넌트가 리랜더링되는 경우

 

리액트에서 컴포넌트가 리랜더링 되는 경우는 크게 3가지 경우이다.

 

1. 컴포넌트 자신의 state가 변경되는 경우

2. 부모 컴포넌트로부터 받은 props가 변경되는 경우

3. 부모 컴포넌트가 변경되는 경우

 

따로 길게 설명하지 않고 샘플코드를 보면서 설명을 하도록 하겠다..

 

 

1. 컴포넌트 자신의 state가 변경되는 경우

import { React, useState } from "react";

export const Render = (props) => {
  const [count, setCount] = useState(0);
  const plusButton = () => {
    setCount(count + 1);
  };
  return (
    <>
      <div>카운트 : {count}</div>
      <button onClick={plusButton}>증가버튼</button>
    </>
  );
};

 

위 코드를 보면 '증가버튼'을 클릭할때마다 Render라는 컴포넌트 자신의 state, 즉 count가 증가한다.

count가 증가할 때마다, 리랜더링이 된다.

 

 

2. 부모 컴포넌트로부터 받은 props가 변경되는 경우

## App.jsx
import { useState } from "react";
import { Render } from "./components/Render";

const App = () => {
  const [count, setCount] = useState(0);
  const setState = () => {
    setCount(count + 1);
  };
  return (
    <>
      <Render data={count}/>
      <button onClick={setState}>App버튼</button>
    </>
  );
};

export default App;

## Render.jsx
import { React } from "react";

export const Render = (props) => {
  console.log("Render 리랜더링 됨");
  return <></>;
};

 

위 코드에서는 부모컴포넌트(App)이 자식컴포넌트(Render)에게 props로 count를 넘겨주고 있다. 

이때 props로 받은 데이터가 1씩 증가하며, 리랜더링 된다.

 

 

3. 부모 컴포넌트가 변경되는 경우

## App.jsx
import { Render } from "./components/Render";

const App = () => {
  const [count, setCount] = useState(0);
  const setState = () => {
    setCount(count + 1);
  };
  return (
    <>
      <div>부모컴포넌트: {count}</div>
      <button onClick={setState}>App버튼</button>
    </>
  );
};

export default App;

## Render.jsx
import { React } from "react";

export const Render = () => {
  console.log("Render 리랜더링 됨");
  return <></>;
};

 

위 코드는 부모컴포넌트로부터 props로 데이터를 받지는 않았지만, 부모컴포넌트에서

state의 값이 변경되며 리랜더링이 일어나며, 자식컴포넌트인 Render 컴포넌트까지 리랜더링 된다.

 

 

결과

0

 

 

성능을 위해 컴포넌트 구조를 구성할 때 고려해야 할 사항

 

아래와 같은 컴포넌트가 있다고 가정해보자.

 

샘플코드1

## App.jsx

import { useState } from "react";
import { Render } from "./components/Render";

const App = () => {
  const [count, setCount] = useState(0);
  const setState = () => {
    setCount(count + 1);
  };
  return (
    <>
      <Render data={"Render1"} />
      <Render data={"Render2"} />
      <Render data={"Render3"} />
      <Render data={"Render4"} />
      <Render data={"Render5"} />
      <div>부모컴포넌트: {count}</div>
      <button onClick={setState}>App버튼</button>
    </>
  );
};

export default App;


## Render.jsx

import { React } from "react";

export const Render = (props) => {
  console.log(props.data);
  return <></>;
};

 

위 코드는 Render이라는 자식 컴포넌트를 5개 가지고 있다.

그리고 Render 컴포넌트와는 전혀 무관한 자신의 state를 변경하는 이벤트를 가진다.

 

만약 위와 같이 코드를 작성하게 되면 부모의 state값이 변경될 때마다 전혀 무관한 자식 컴포넌트들 또한

리랜더링이 되버린다.

 

결과

0

위를 보면 부모컴포넌트가 1번 클릭될때마다 콘솔에 로그가 5개씩 찍히는데,

부모컴포넌트의 state값이 변경될때마다 5개의 자식컴포넌트가 리랜더링 된다는 의미이다.

 

지금 같은 경우에는 컴포넌트가 5개 밖에 없고 가볍기 때문에 별 문제가 안되지만

만약 컴포넌트 개수도 많아지고 컴포넌트가 무겁다면? 성능에 영향이 갈 것이다.

 

그렇기 때문에 전혀 무관한 기능을 한다면 아래와 같이 따로 컴포넌트로 작성하는 것이 좋다.

 

 

샘플코드2

## App.jsx

import { Render } from "./components/Render";
import { Count } from "./components/Count";

const App = () => {
  return (
    <>
      <Render data={"Render1"} />
      <Render data={"Render2"} />
      <Render data={"Render3"} />
      <Render data={"Render4"} />
      <Render data={"Render5"} />
      <Count />
    </>
  );
};

export default App;


## Render.jsx

import { React } from "react";

export const Render = (props) => {
  console.log(props.data);
  return <></>;
};


## Count.jsx

import { React } from "react";
import { useState } from "react";

export const Count = () => {
  const [count, setCount] = useState(0);
  const setState = () => {
    setCount(count + 1);
  };
  console.log("Count: " + count);
  return (
    <>
      <div>부모컴포넌트: {count}</div>
      <button onClick={setState}>App버튼</button>
    </>
  );
};

 

 

결과

0

 

위 코드를 보면 같은 기능을 하지만 부모컴포넌트에서 관리하던 state를 따로 컴포넌트로 빼서

사용하였다. 하지만 count의 값이 변경이 되도 Render 컴포넌트는 리랜더링 되지 않는다.

 

이렇게 하면 같은 기능을 하더라도 필요한 부분만 리랜더링이 되기 때문에 성능에 도움이 된다.

 

 

결론 : 연관이 없는 state를 부모컴포넌트가 아닌 따로 컴포넌트로 빼서 작성하도록 하자.

 

 

728x90
profile

개발공작소

@모찌바라기

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!