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 шт):
Подскажите как можно исправить данную ситуацию и исправима ли она принципиально без уменьшения кол-ва отображаемых 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>