React Select с очень большими списками опций

У меня есть компонент select, который должен обрабатывать около 7000 опций. Я сталкиваюсь с двумя проблемами.

1) при наборе в параметре поиска вещи загружаются слишком медленно.

2) Мне нужно отфильтровать все параметры и отключить параметры, которые были ранее выбраны (из значений, которые я загружаю из базы данных) или только что были выбраны на этой странице загрузки.

Для проблемы № 1 я попытался использовать https://github.com/bvaughn/react-select-fast-filter-options и он работает при загрузке первой страницы. Я сталкиваюсь с проблемами всякий раз, когда пытаюсь каким-либо образом изменить параметры, как вы увидите, я изначально пытаюсь загрузить параметры с помощью вызова ajax (который я могу изменить) или, если мне нужно отключить параметры динамически, я думаю, что это может привести к поломке Это.

Для задачи № 2, когда я пытаюсь отфильтровать все эти опции, это занимает много времени, потому что я зацикливаюсь на всех 7 000 опций каждый раз, когда человек делает выбор в списке.

Некоторое руководство по этому вопросу может быть полезным. Для дальнейшего контекста вот код, который у меня есть:

import React, {Component} from 'react'
import PropTypes from 'prop-types';
import 'react-select/dist/react-select.css'
import 'react-virtualized/styles.css'
import 'react-virtualized-select/styles.css'
import VirtualizedSelect from 'react-virtualized-select'
import axios from 'axios';

class StockSearch extends Component {
    static propTypes = {
        exchanges: PropTypes.array.isRequired,
        onSelectChange: PropTypes.func.isRequired,
        searchDisabled: PropTypes.bool.isRequired,
        picks: PropTypes.array.isRequired,
        stock_edit_to_show: PropTypes.number
    }

    state = {
        stocks: [],
        selected: []
    }

    componentWillReceiveProps = (nextProps) => {

    }

    /**
     * Component Bridge Function
     * @param stock_id stocks id in the database
     */
    stockSearchChange = (stock_id) => {
        this.props.onSelectChange(stock_id);
    }

    componentWillMount = () => {
        this.fetchStocks(this.props.exchanges);
    }

    /**
     * Responsible for fetching all of the stocks in the database
     * @param exchanges comma denominated list of exchange ids
     */
    fetchStocks = (exchanges) => {
        let stringExchanges = exchanges.join();
        axios.get('/stock-search-data-by-exchange/', {
            params: {
               exchanges: stringExchanges
            }
        })
        .then(response => {
            this.setState({
                stocks: response.data
            })
        })
        .catch(error => {
            console.log(error);
        })
    }

    /**
     * handles selected option from the stock select
     * @param selectedOption
     */
    handleSelect = (selectedOption) => {
        this.stockSearchChange(selectedOption.value);
    }

    render() {
        return (
            <div className="stock-search-container">
                <VirtualizedSelect
                    name="stock-search"
                    options={this.state.stocks}
                    placeholder="Type or select a stock here..."
                    onChange={this.handleSelect}
                    disabled={this.props.searchDisabled}
                    value={this.props.stock_edit_to_show}
                />
            </div>
        )
    }
}

export default StockSearch;

0 ответов

Для проблемы #1, response-windowed-select было очень полезно для меня в подобных обстоятельствах: https://github.com/jacobworrel/react-windowed-select

Для проблемы #2 я обнаружил, что реагирует на перерисовку окна очень быстро. Вы можете поэкспериментировать с фильтрами своего набора данных, вот фрагмент кода, с которого можно начать:

const startTime = Date.now()

// Create a 7000 element array with a bunch of content, in this case junk strings
array = [...Array(7000)].map(i => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5))
const arrayBuiltTime = Date.now()

// Filter out any string with the letter 'q' to emulate a filtering operation
const filteredArray = array.filter(i => !i.includes('q') )
const doneTime = Date.now()

// See how long it takes :-)
console.log(startTime)
console.log(arrayBuiltTime)
console.log(doneTime)

https://codepen.io/smeckman/pen/zYOrjJa?editors=1111

Другие вопросы по тегам