React|最適化コンポーネント性能04方法2(反応−仮想化利用)


🔶 既存のコードの問題
🔹 非効率
既存の構成部品(2500構成部品)スクロールのみ(表示、2491構成部品)→レンダリング
🔹 システムリソースの浪費
アレイが変更された場合
→構成部品をアレイの先頭から末尾に変換する(構成部品内部map関数)
→見えない部分まで(2491素子)
🔶 react-仮想化機能

  • 非表示(スクロール前)構成部品→x&サイズのみをレンダリング

  • スクロール→レンダリング
  • 🔶 使用方法
    🔹 設定$ yarn add react-virtualized🔹 に道を教える
    ⑪概要&前処理

  • 提供されたリストコンポーネントの使用→パフォーマンスの最適化

  • プリプロセッシング
    各項目の実際のサイズを決定→px単位
  • のサイズを決定→第2項を決定

  • n/a.理由
    2番目の項目から枠線を含めます.(第1項→枠なし)
  • サンプルコード
  • TodoList.js
  • import React, { useCallback } from 'react';
    import TodoListItem from './TodoListItem';
    import './TodoList.scss';
    import { List } from 'react-virtualized';
    
    const TodoList = ({ todos, onRemove, onToggle }) => {
      const rowRenderer = useCallback(
        ({ key, index, style }) => {
          const todo = todos[index];
          return (
            <TodoListItem
              todo={todo}
              key={key}
              onRemove={onRemove}
              onToggle={onToggle}
              style={style}
            />
          );
        },
        [todos, onRemove, onToggle],
      );
    
      return (
        <List
          className="TodoList"
          width={512} // 전체 크기
          height={513} // 전체 높이
          rowCount={todos.length} // 항목 개수
          rowHeight={57} // 항목 높이
          rowRenderer={rowRenderer} // 항목 렌더링 시 쓰는 함수
          list={todos} // 배열
          style={{ outline: 'none' }} // List에 기본 적용되는 outline 스타일 제거
        />
      );
    };
    
    export default React.memo(TodoList);
  • TodoListItem.js
  • 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,
      (prevProps, nextProps) => prevProps.todo === nextProps.todo, // propsAreEqual 함수 사용 -> 특정 값들만 비교
    );
  • TodoListItem.scss
  • .TodoListItem-virtualized {
      & + & {
        border-top: 1px solid #dee2e6;
      }
      &:nth-child(even) {
        background: #f8f9fa;
      }
    }
    
    (...)
    97 rowReduser関数
    react-仮想化されたListコンポーネントで各アイテムをレンダリングする場合に使用

  • Listコンポーネントのprops

  • パラメータ:index、key、style値→オブジェクトタイプとして受信して使用
  • [リスト](List)コンポーネントを使用する場合に必要なアイテム
    転送されたpropsの使用→自動最適化
  • リストのフルサイズ(幅、高さ)
  • 高さ
  • 各項目をレンダリングするときに使用する関数

  • 修正して97 rowReduserの戻り素子に適応→props

  • 構成部品TodoListItem.js , TodoListItem.scss

  • [修正]divで一番上に包む

  • className(TodoListItem-virtualized)設定
    目的:構成部品間で枠線を正しく位置決めする(→& + &)

  • アプリケーションprops(style)
    目的:単品品に異なる背景色を適用する(→&:nth-child(even))