ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React TodoList] 불변성, 최적화, 렌더링 최적화
    React/일정관리 프로젝트 2023. 3. 15. 09:44

    리액트 투두리스트 보완

     

     

    불변성의 중요성

    불변성이란?
    기존의 값을 수정하지 않으면서 새로운 값을 만들어 내는 것

     

     

    TodoList 컴포넌트 최적화 하기

    리스트 내부에서 사용하는 컴포넌트도 최적화 해야 하고, 

    리스트로 사용되는 컴포넌트 자체도 최적화해 주는 것이 좋다.

     

     

     

    react-virtualized를 사용한 렌더링 최적화 하기

    리스트 컴포넌트에서 스크롤 되기 전에 보이지 않는 컴포넌트는 렌더링 하지 않고 크기만 차지하게 끔 할 수 있다.

    스크롤 이벤트 발생 시, 스크롤 위치에서 보여 주어야 할 컴포넌트를 자연스럽게 렌더링 시킨다.

    이 라이브러리를 사용하면 낭비되는 자원을 아주 쉽게 아낄 수 있다. 

     

    사용방법

     

    1. 패키지 설치 

    npm install react-virtualized

     

    2. UI 컴포넌트 px 알아보기

     

     

     

    3. TodoList.js 수정

     

    import React, { useCallback } from 'react';
    import { List } from 'react-virtualized';
    import TodoListItem from './TodoListItem';
    import './TodoList.scss';
    
    const TodoList = ({ todos, onRemove, onToggle }) => {
      const rowRenderer = useCallback(
        ({ index, key, style }) => {
          const todo = todos[index];
          return (
            <TodoListItem
              todo={todo}
              key={key}
              onRemove={onRemove}
              onToggle={onToggle}
              style={style}
            />
          );
        },
        [onRemove, onToggle, todos],
      );
      return (
        // 각 항목의 길이는 가로 512, 세로 56.67(첫번째 칸은 테두리가 없어 세로 56) 이다.
        <List
          className="TodoList"
          width={512} // 전체 크기
          height={453.44} // 전체 높이
          rowCount={todos.length} // 항목 개수
          rowHeight={56.67} // 항목 높이
          rowRenderer={rowRenderer} // 항목을 렌더링할 때 쓰는 함수
          list={todos} // 배열
          style={{ outline: 'none' }} // List에 기본 적용되는 outline 스타일 제거
        />
      );
    };
    
    export default React.memo(TodoList);

     

     

    4. TodoListItem 

    import React from 'react';
    import {
      MdCheckBoxOutlineBlank,
      MdCheckBox,
      MdRemoveCircleOutline,
    } from 'react-icons/md';
    import cn from 'classnames';
    import './TodoListItem.scss';
    
    const TodoListItem = ({ todo, onRemove, onToggle, style }) => {
      const { id, text, checked } = todo;
    
      return (
        <div className="TodoListItem-virtualized" style={style}>
          <div className="TodoListItem">
            <div
              className={cn('checkbox', { checked })}
              onClick={() => onToggle(id)}
            >
              {checked ? <MdCheckBox /> : <MdCheckBoxOutlineBlank />}
              <div className="text">{text}</div>
            </div>
            <div className="remove" onClick={() => onRemove(id)}>
              <MdRemoveCircleOutline />
            </div>
          </div>
        </div>
      );
    };
    
    export default React.memo(TodoListItem);

     

     

    5. TodoListItem.scss

    .TodoListItem-virtualized {
      &:nth-child(even) {
        background-color: #f8f9fa;
      }
      & + & {
        border-top: 1px solid #dee2e6;
      }
    
    }
    .TodoListItem{
      padding: 1rem;
      display: flex;
      align-items: center;
      
      .checkbox{
        cursor: pointer;
        flex : 1;
        display: flex;
        align-items: center;
        svg {
          font-size:  1.5rem;
        }
        .text {
          margin-left: 0.5rem;
          flex : 1
        }
        &.checked {
          svg{
            color : #22b8cf;
          }
          .text{
            color :#adb5bd;
            text-decoration: line-through;
          }
        }
      }
      .remove {
        display: flex;
        align-items: center;
        font-size: 1.5rem;
        color:#ff6b6b;
        cursor: pointer;
        &.hover {
          color :#ff8787;
        }
      }
    
      
    }

     

     

    Final , 성능 측정

Designed by Tistory.