【问题标题】:Huge freezes when rendering long selects in React在 React 中渲染长选择时出现巨大的冻结
【发布时间】:2021-07-22 13:14:23
【问题描述】:

我有一张 50-200 行的桌子。它可以使用文本值渲染,但是当我添加选择时,它开始在渲染时冻结。每个选择有近 1500 个选项。

即表体:

<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 接近 1500。当我不渲染选择时,冻结就消失了。但我确实需要让我们的用户选择值。我怎样才能做到这一点?

也许在mouseOver 上将一些div 转换为select

【问题讨论】:

  • 查看备用选择组件,例如 react-select.com 或将选择包装到您可以使用的组件中,例如React.memo().

标签: reactjs


【解决方案1】:

对此进行优化的一种方法是为选择输入创建一个组件。 这必须是一个功能组件,它允许 React 优化选择字段的一些不必要的重新渲染。

此外,这个过滤器的结果必须被记忆:

subjects.filter(subject => subject.type == 'All' || subject.type == 'OO')

更多关于记忆的信息here

const memoizedSubjects = useMemo(
  () => subjects.filter(subject => subject.type == 'All' || subject.type == 'OO'),
  []
);

【讨论】:

  • 现在我使用 React-Select 并且没问题。谢谢
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-10
  • 1970-01-01
  • 2022-10-07
  • 2011-11-22
  • 2022-01-21
相关资源
最近更新 更多