컴포넌트 최적화(1) - React.Memo

김재한·2023년 2월 12일
0

React 기초

목록 보기
2/9

React.Memo를 사용해 불필요한 리렌더링 방지

리액트 개발을 하다보면 눈에는 보이지 않지만 많은 컴포넌트들이 불필요하게 리렌더링 되는 경우들이 많다. 실제로 console.log를 찍어 확인해 보면 무수히 많은 로그들이 촤라라 올라오는 것을 확인할 수 있다. 오늘은 React.Memo를 사용해 컴포넌트를 최적화 하는 방법을 정리해 보려고 한다.

[ 컴포넌트가 렌더링 되는 경우 ]

1. 부모 컴포넌트가 렌더링 될 경우.
2. 전달받은 props 값이 업데이트 되었을 경우. 
3. 컴포넌트 내 State가 변경되었을 경우.

전달받은 props 값이나 컴포넌트 내 State가 변경되지 않았을 경우에는 렌더링을 다시 할 이유가 없다. React.Memo는 props가 변경되지 않았을 경우 마지막 렌더링 결과를 재사용 함으로써 불필요한 리렌더링을 방지할 수 있다.

1. React.memo 사용법

const MyComponent = React.memo(({props1, props2}) => {
  return <></>
})

export default MyComponent;

또는

function MyComponent({props1, props2}){
  return <></>
}
export default React.memo(MyComponent)

2. 적용해보기


[app.js]

function App() {
  console.log('App.js Rendering')
  const [todoData,setTodoData] = useState([])
  const [inputValue, setInputValue] = useState('')
  const handleSubmit = (e) =>{
    e.preventDefault()
    let newTodo ={
      id: Date.now(),
      title: inputValue,
      completed: false
    }
    setTodoData([...todoData,newTodo])
    setInputValue('')
  }
  return (
    <div className="flex items-center justify-center w-screen h-screen bg-blue-100  ">
      <div className="w-full p-6 m-4 bg-white rounded shadow lg:w-3/4 lg:max-w-lg">
        <div  className="flex justify-between mb-3">
          <h1>할 일 목록</h1>
        </div>
        <Lists todoData={todoData} setTodoData={setTodoData}/>
        <Form handleSubmit={handleSubmit} inputValue={inputValue} setInputValue={setInputValue} />
      </div>
    </div>
  );
}

export default App;

React.memo가 적용되지 않는다면, input 태그에 입력이 들어올 때 마다 inputValue가 변경되므로 부모 app 컴포넌트가 렌더링되어 모든 컴포넌트들이 리렌더링 되어진다.

React.memo 적용해 주면 실제 리렌더링이 필요한 app.js 와 From 컴포넌트만 바뀌는 것을 확인 할 수 있다.

[Lists.js]

import {DragDropContext, Draggable, Droppable} from "react-beautiful-dnd";
import List from "./List";
import React from"react"

function Lists({todoData, setTodoData}) {
  console.log('Lists.js Rendering')
    ~~~~ 
  return (
    <div>
    	<List ~~/>
    	~~~~
    </div>
  );
}
export default React.memo(Lists)

[List.js]

import React, { useState } from 'react';

const List = React.memo(({ id, title, completed, todoData, setTodoData, provided, snapshot }) => {
  console.log('List.js Rendering')
  ~~~~
  return (
    <div>
     ~~~~
     /div>
  )
});

export default List;

[Form.js]

export default function Form({handleSubmit, inputValue, setInputValue}) {
  console.log('Form.js Rendering')
  const handleChange = (e) => {
    setInputValue(e.target.value)
  }

  return (
    <div>
      <form  onSubmit={handleSubmit} className="flex pt-2 ">
        <input
          type="text"
          name="value"
          className="w-full px-3 py-2 mr-4 text-gray-500 border rounded shadow"
          placeholder='해야 할 일을 입력하세요.'
          value={inputValue}
          onChange={handleChange}
        />
        <input
          type="submit"
          value="입력"
          className="p-2 text-blue-400 border-2 border-blue-400 rounded hover:text-white hover:bg-blue-200"
        />
      </form>
    </div>
  );
}


실제 리렌더링이 필요한 app 과 Form 컴포넌트만 리렌더링 되는 것을 확인할 수 있다.

0개의 댓글