Задать вопрос
@wiigusev
Изучаю Web разработку

Как сделать всплывающие подсказки при вводе?

Здравствуйте.
Основной вопрос:
1. Как сделать, чтобы при вводе информации в поле (TextField из MaterialUI) появлялось ниже поля окно с подсказками, которые грузим с сервера. При этом, чтобы данные из этого поля - TextField тоже отправлялись на сервер и отправке формы.
Дополнительный вопрос:
2. Как при клике на одну из подсказок заполнить форму данными, которые приходят с сервера
  • Вопрос задан
  • 1913 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
1. Повесить слушатель на onChange, который будет делать соответствующий запрос на сервер. По приходу данные надо отрисовывать. Лучше использовать debounce и проверку минимальной длины строки перед запросом.
2. Повесить на подсказку слушатель onClick и менять в обработчике значение нужного input.

Простой пример реализации подобной логики:
import React, { useState, useRef, useCallback, useMemo } from 'react';
import debounce from 'lodash/debounce';
import { fetchSomeData } from './someplace';

const Example = () => {
  const [results, setResults] = useState([]);
  const inputEl = useRef(null);

  const handleTintClick = useCallback((value) => {
    inputEl.current.value = value;
  }, [inputEl]);

  const handleInputChange = useMemo(() => debounce(e => {
    const { value } = e.target;

    if (value.length < 3) return;

    fetchSomeData(value).then(setResults);
  }, 800), []);

  return (
    <>
      <input ref={inputEl} onChange={handleInputChange} />
      {results.length > 0 && (
        <ul>
          {results.map((result, i) => (
            <li
              onClick={() => hanldeTintClick(result.title}}
              key={result.id}
            >
              {result.title}
            </li>
          )}
        </ul>
      )}
    </>
  );
};

debounce нужен чтобы оптимизировать количество запросов к серверу. Колбек будет вызван только когда пользователь сделает паузу во вводе на 800мс, если это много, то таймаут можно сделать меньше.
useMemo вместо useCallback, чтобы не вызвать debounce каждую перерисовку.

Понятное дело, что в реальном коде вместо ul/li должен быть стилизованный компонент. В документации MateralUI есть примеры использования их компонентов.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@davidnum95
https://material-ui.com/components/popover/
При фокусе на input меняем open на true. Внутри Popover'a грузим и взаимодействуем как хотим.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы