Skip to content

Некрасивое поведение InputAutocomplete с closeOnSelect #1149

Open
penartur opened this issue May 6, 2020 · 0 comments
Open

Comments

@penartur
Copy link

penartur commented May 6, 2020

Шаги для воспроизведения

Используем InputAutocomplete с closeOnSelect=true на странице, содержимое которой сильно меняется (включая размеры элементов) в зависимости от выбранного значения.
Выбираем значение в InputAutocomplete.

Ожидаемое поведение

Выпадающее меню со списком значений исчезает, содержимое страницы меняется.

Актуальное поведение

В некоторых случаях содержимое страницы меняется, при этом выпадающее меню перемещается вслед за самим InputAutocomplete; через доли секунды после этого выпадающее меню исчезает.

Для пользователя это выглядит так, как будто всё дёргается (выпадающее меню исчезло со старого места, но появилось на доли секунды в новом месте).

Возможное решение

Кажется, проблема вызвана вот этим фрагментом кода:

this.inputBlurTimeout = setTimeout(() => this.input.blur(), 0);

То есть, при closeOnSelect выпадающее меню не скрывается напрямую - а опосредованно через таймер вызывается blur у Input, который вызывает blur у HTML-элемента, из-за которого когда-то потом вызовется обработчик handleInputBlur у Input, который через таймер вызовет solveFocused, который наконец-то проставит в state оба поля inputFocused и menuFocused в false, так, чтобы выпадающее меню не отображалось.

Проблема в том, что пока идёт эта цепочка таймер -> HTML-событие -> ещё один таймер, мы давным-давно успеет обработать this.props.onItemSelect, и реакт давным-давно успеет сделать ререндер страницы с учётом нового значения, и InputAutocomplete давным-давно успеет уехать на другой конец экрана вместе со своим выпавшим меню.

Если в

        if (this.props.closeOnSelect) {
            this.inputBlurTimeout = setTimeout(() => this.input.blur(), 0);

добавить строку

        if (this.props.closeOnSelect) {
            this.setState({ inputFocused: false, menuFocused: false });
            this.inputBlurTimeout = setTimeout(() => this.input.blur(), 0);

то эта проблема решается. Но, может быть, появляются какие-то новые.

Исходно возможность закрытия по клику была добавлена в #283 ; кажется, проблема присутствовала ещё тогда, но не вижу там никакого обсуждения.

Окружение

  • Используемая версия библиотеки: 14.0.0
  • Имя и версия браузера: Chrome 80.0.3987.149
  • Имя и версия ОС: Windows 10 1909 (18363.693)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant