React + Ant design: задержки при отображении и взаимодействии с большим (200+) кол-вом Checkbox

Отрисовываю компонент с большим кол-вом Checkbox элементов (200+), разбитых на группы:

        <div className='lm-list'>
            {
                groups.map((group, index) => (
                    <ComponentListLetterBlock 
                        key         = {index} 
                        group       = {group} 
                        selectedIDs = {props.selectedIDs} 
                        onCheck     = {props.onCheckItem}
                    />
                ))
            }
        </div>

где

// компонент: элемент группы списка
const ComponentListLetterItem = (props: IProps_ListLetterItem) => {
    // отрисовать компонент
    return (
        <div className='lm-block-item'>
            <Checkbox
                checked     = {props.checked}
                onChange    = {(e: any) => props.onCheck(props.item.id, e?.target?.checked)}
            >
                <div className="lm-item-name">{props.item.name ? props.item.name : props.item.nickname }</div>
            </Checkbox>
        </div>    
    );
};


// компонент: группа списка
const ComponentListLetterBlock = (props: IProps_ListLetterBlock) => {
    // отрисовать компонент
    return (
        <div className='lm-block'>
            <h3 className="lm-block-letter">{props.group.id}</h3>
            {
                props.group.values.map((elem, index) => (
                    <ComponentListLetterItem
                        key         = {index}
                        item        = {elem}
                        checked     = {props.selectedIDs.includes(elem.id)}
                        onCheck     = {props.onCheck}
                    />
                ))
            }
        </div>
    );
}

и сам компонент отрисовывается первый раз медленно и при каждом нажатии на любой checkbox большие задержки выставления и снятия отметки (видно даже глазом)

оборачивание в React.memo компонентов ComponentListLetterBlock и ComponentListLetterItem ни к чему не привело

Подскажите как можно исправить данную ситуацию и исправима ли она принципиально без уменьшения кол-ва отображаемых Checkbox?


Ответы (1 шт):

Автор решения: ksa

Подскажите как можно исправить данную ситуацию и исправима ли она принципиально без уменьшения кол-ва отображаемых Checkbox?

Вот супер не оптимальное приложение в котором 10 групп и в каждой группе по 30 чеков...

Все чеки ставятся и снимаются быстро.

//
const Itm = ({obj, n, act}) => {
  const fn = () => act(n, obj.id)
  return <li>
    <input type='checkbox' onChange={fn} checked={obj.v} />
  </li>
}
//
const Grp = ({obj, act}) => {
  return <li>
    <p>{obj.name}</p>
    <ol>
      {obj?.arr.map(o => <Itm key={o.id} obj={o} n={obj.id} act={act} />)}
    </ol>
  </li>
}
//
const App = () => {
  const {arr, act} = useData()
  return <ul>
    {arr.map(o => <Grp key={o.id} obj={o} act={act} />)}
  </ul>
}

const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<App />);
//
function useData(){
  const [arr, setArr] = React.useState([])
  React.useEffect(_ => setArr(data(10, 30)), [])
  const act = (n, m) => setArr(old => old.map(o => o.id === n
    ? {...o, arr: o.arr.map(o => o.id === m
      ? {...o, v: !o.v}
      : o
    )}
    : o
  ))
  return {arr, act}
}
//
function data(n, m){
  return Array.from({length: n}, (_, i) => {
    return {
      id: i,
      name: 'Группа ' + (i + 1),
      arr: Array.from({length: m}, (_, i) => {
        return {
          id: i,
          v: false
        }
      })
    }
  })
}
ul,
ol { 
  list-style-type: none;
  padding-left: 0;
}
ol {
  display: flex;
}
<div id="like_button_container"></div>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>

→ Ссылка