【问题标题】:Efficiently rendering large list of data in React Select在 React Select 中有效地呈现大量数据
【发布时间】:2020-06-02 00:29:03
【问题描述】:

在可搜索的反应选择下拉列表中呈现大量数据的最佳方式是什么?我查看了窗口化,其中 DOM 节点仅为在视口中可见的项目创建。这可以通过在 react-select 旁边使用 react-window 包来完成。但是,我想知道是否有比这更好的方法。

这是使用 react-window 和 react-select 的窗口实现

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";
import { FixedSizeList as List } from "react-window";

import "./styles.css";

const options = [];
for (let i = 0; i < 10000; i = i + 1) {
  options.push({ value: i, label: `Option ${i}` });
}

const height = 35;

class MenuList extends Component {
  render() {
    const { options, children, maxHeight, getValue } = this.props;
    const [value] = getValue();
    const initialOffset = options.indexOf(value) * height;

    return (
      <List
        height={maxHeight}
        itemCount={children.length}
        itemSize={height}
        initialScrollOffset={initialOffset}
      >
        {({ index, style }) => <div style={style}>{children[index]}</div>}
      </List>
    );
  }
}

const App = () => <Select components={{ MenuList }} options={options} />;

ReactDOM.render(<App />, document.getElementById("root"));

【问题讨论】:

  • 当用户滚动到下拉列表底部时,我会实现延迟加载并添加到下拉列表中。 React 只会渲染不在页面上或使用 key 属性更新的项目。

标签: reactjs react-select react-window


【解决方案1】:

我将您提到的解决方案(react-window)与 filterOption 解决方案以及讨论较少的 react-async 组件结合在一起。这对我来说效果很好。

react-window 将执行某种“延迟加载”,而异步响应会在显示搜索查询之前显示加载符号。这些一起让它感觉更自然(我有 7000 多个选项)。

这是我第一次回复帖子,所以如果(任何人)有问题,请告诉我,我会尽力回答

import React, { Component } from "react";
import AsyncSelect from "react-select/async";
import { FixedSizeList as List } from "react-window";
import { createFilter } from "react-select";

import "./styles.css";

const TestSelect = (vendorOptions) => {


const options = [];
for (let i = 0; i < vendorOptions["vendorOptions"].length; i = i + 1) {
  options.push({ value: vendorOptions["vendorOptions"][i], label: `${vendorOptions["vendorOptions"][i]}` });
}

const loadOptions = (inputValue, callback) => {
    setTimeout(() => {
      callback(options);
    }, 1000);
  };


const height = 35;

class MenuList extends Component {
  render() {
    const { options, children, maxHeight, getValue } = this.props;
    const [value] = getValue();
    const initialOffset = options.indexOf(value) * height;

    return (
      <List
        height={maxHeight}
        itemCount={children.length}
        itemSize={height}
        initialScrollOffset={initialOffset}
      >
        {({ index, style }) => <div style={style}>{children[index]}</div>}
      </List>
    );
  }
}

const TestSelectComponent = () => {
    
    return(
        <div className ="testDropdown">
          <AsyncSelect components={{ MenuList }} cacheOptions defaultOptions loadOptions={loadOptions} filterOption={createFilter({ ignoreAccents: false })}/>
        </div>
    )
}
    return (
    <TestSelectComponent />
    )
}
export default TestSelect

【讨论】:

    【解决方案2】:

    如果你看你会发现默认值是ignoreAccents: true。此默认设置使 react-select 调用一个名为 stripDiacritics 的昂贵函数两次。这会导致性能问题。

    在 react-select 中包含 ignoreAccents: false。

    示例:filterOption={createFilter({ ignoreAccents: false })}

    【讨论】:

      猜你喜欢
      • 2020-08-30
      • 2018-06-09
      • 2018-06-09
      • 1970-01-01
      • 2020-06-01
      • 2020-08-11
      • 2019-02-10
      • 1970-01-01
      • 2021-08-17
      相关资源
      最近更新 更多