Reputation: 1671
I have a table, 50-200 rows. It renders OK with text values, but when I add selects, it starts to freeze on render. The selects have nearly 1500 options each.
That is the table body:
<tbody className="tbody">
{tableSubjects.map((item, idx) => (
<tr key={item.id} className="tr">
<td className="td">{idx + 1}</td>
<td
className={`td object ${errors[`educational_documents.10.data.table_subjects[${idx}].subject_id`] ? "error" : ""
}`}
>
<select
tabIndex="-1"
className="input table-select w-100"
id={`educational_documents.10.data.table_subjects[${idx}].subject_id`}
onChange={(e) => handleChange_subject_id(e, item)}
required
readOnly={!edit}
defaultValue={_.get(tableSubjects, `[${idx}].subject_id`, '')}
>
<option value="" disabled>
Select one
</option>
{subjects.filter(subject => subject.type == 'All' || subject.type == 'OO').map((subject) => (
<option key={subject.id} value={subject.id}>
{subject.code} {subject.name}
</option>
))}
</select>
<span className="error-message w-100">
{errors[`educational_documents.10.data.table_subjects[${idx}].subject_id`]}
</span>
</td>
<td className="td mark">
<input
type="number"
readOnly={!edit}
id={`educational_documents.10.data.table_subjects[${idx}].subject_mark`}
min="0"
step="1"
max={scoreSystem}
class="input table-input w-100"
required
onChange={(e) => handleChange_subject_mark(e, item)}
defaultValue={_.get(tableSubjects, `[${idx}].subject_mark`, '')}
onKeyDown={window.preventTab}
/>
</td>
<td className="td actions ">
<button type="button"
tabIndex="-1"
readOnly={!edit}
className="btn trash"
onMouseDown={(e) => removeTableSubject(e, item)}
>
<i className="uil uil-trash-alt"></i>
</button>
</td>
</tr>
))}
</tbody>
subjects.length
is nearly 1500. When I don't render selects, freezes are gone. But I do need to let our users to select the value. How can I achieve that?
Maybe transform some div
into select
on mouseOver
?
Upvotes: 0
Views: 1519
Reputation: 616
One way to optimize this is to create a component for select input. This has to be a functional component which would allow React to optimize away some unnecessary re-renderings of the select field.
Also, the result of this filter has to be memoized:
subjects.filter(subject => subject.type == 'All' || subject.type == 'OO')
More on memoization here
const memoizedSubjects = useMemo(
() => subjects.filter(subject => subject.type == 'All' || subject.type == 'OO'),
[]
);
Upvotes: 1