1

Тема: Dropdown з інкрементним пошуком: Як це правильно зробити react-way?

import React, { useState } from "react";
import PropTypes from "prop-types";
import { Select } from "antd";

import { api } from "../../api";
import { useFetch } from "../../hooks";

function Dropdown({ value, account, mode, onChange, ...rest }) {
    const [filter, setFilter] = useState();
    let items = useFetch({
        request: api.something.getItems,
        payload: { account, mode, filter }
    });

    let options = [];
    if (items?.data?.items?.length) {
        options = items.data.items.map(el => (
            <Select.Option
                key={el.id}
                value={el.id}
            >
                {el.title}
            </Select.Option>
        ));
    }

    const search = value => {
        if (value) {
            setFilter(JSON.stringify([
               {
                   field: "title",
                   operator: "contains",
                   value
               }
            ]));
        } else {
            setFilter();
        }
    };

    return (
        <Select
            value={value}
            loading={items.loading}
            onChange={onChange}
            showSearch
            onSearch={search}
            {...rest}
        >
            {options}
        </Select>
    );
}

Dropdown.propTypes = {
    value: PropTypes.string,
    account: PropTypes.string.isRequired,
    mode: PropTypes.bool.isRequired,
    onChange: PropTypes.func.isRequired
};

export default Dropdown;

useFetch - кастомний хук, що при зміні параметрів робить новий запит (через axios) і повертає об'єкт з даними, в т. ч. властивість items.loading відображає поточний стан запиту.

Виходить приблизно така штука:
Перший рендер items = null, Select рендериться без опцій, але це відбувається дуже на короткий час і вже буквально на...
...другий рендер items.loading = true, items.data = null, Select рендериться без опцій, але крутиться спіннер, що інформує про запит до бекенду.
Третій рендер відбувається коли приходять дані, нарешті items.data.items - це масив даних, options генерується і Select рендериться з першою порцією даних (10 шт).

До цього моменту все працює ок.

Тепер, коли ми починаєм в дропдауні вводити текст, спрацьовує функція search, яка встановлює filter, знову відправляється запит, відбувається кілька рендерів (здається по числу натиснутих клавіш), в результаті через console.log я бачу, що дані в items.data.items з'являються, options генерується, як треба, а от Select з новою порцією даних чомусь не перерендерюється.

Мабуть, я вже закостенів мізками і ніколи не зможу в'їхати в цю всю трахомудію реактівську. Довго намагався щось сам ліпити, але здаюсь, вирішив звернуится за допомогою. Що можуть порадити молоді спеціалісти з цього приводу?

2

Re: Dropdown з інкрементним пошуком: Як це правильно зробити react-way?

Розібрався, в чому проблема була... одну опцію пропустив отут:

    return (
        <Select
            value={value}
            loading={items.loading}
            onChange={onChange}
            showSearch
            onSearch={search}
            filterOption={false}
            {...rest}
        >
            {options}
        </Select>
    );

а саме filterOption={false}, через що пошук на бекенді конфліктував з пошуком на фронтенді і все йшло до дідька.