Содержание
Вам когда-нибудь было интересно узнать, как такие платформы, как Notion, Hashnode и другие, динамически изменяют высоту заголовков страниц или статей (текстовых областей)? Если вы заметили, при вводе содержимого в текстовую область высота динамически рассчитывается на основе контента на этих платформах.
Я хотел добиться такого же поведения на странице статей OpenMetadata Knowledge. В этой статье я расскажу о том, как я решил эту задачу с помощью пользовательского хука.
Пользовательский хук
Пользовательские хуки в ReactJS - это многократно используемые части кода, которые инкапсулируют логику и управление состоянием.
Итак, давайте перейдем к использованию пользовательского хука useAutoSizeTextArea, который будет динамически регулировать высоту текстовой области в зависимости от ее содержимого.
Он принимает на вход три параметра
id: Строка, представляющая уникальный идентификатор элемента textarea.
textAreaRef: Ссылка на элемент HTMLTextAreaElement, размер которого вы хотите изменить. Это может быть null, если текстовая область еще не отрисована.
value: Строка, представляющая содержимое текстовой области.
Внутри хука useLayoutEffect проверяется, доступен ли textAreaRef. Если нет, он пытается найти элемент textarea по указанному id, запрашивая DOM документа.
Если действительный элемент textarea найден (либо через textAreaRef, либо путем запроса DOM с указанным id), он приступает к регулировке высоты textarea в соответствии с его содержимым. Для этого нужно выполнить следующие шаги.
Сначала он устанавливает style.height текстового поля в 0px. Это временно скрывает текстовую область, чтобы избежать мерцания при расчете высоты прокрутки.
Затем вычисляется высота прокрутки (scrollHeight) текстовой области, которая представляет собой полную высоту содержимого, даже если в данный момент оно не видно из-за того, что высота установлена в 0px.
Наконец, он устанавливает style.height текстовой области на рассчитанную scrollHeight, эффективно изменяя размер текстовой области для соответствия ее содержимому.
Хук настроен на запуск при изменении любой из зависимостей ([textAreaRef, id, value]). Это означает, что если textAreaRef, id или value текстовой области изменится, хук пересчитает высоту текстовой области, чтобы она соответствовала новому содержимому.
Теперь давайте включим этот пользовательский хук в пример приложения.
Пример
В этом примере я буду использовать CodeSandbox, чтобы избежать локальной настройки и сосредоточиться на теме этого блога.
Здесь у нас есть простой компонент App, который рендерит h2 и textarea.
const textAreaRef = useRef < HTMLTextAreaElement > null;
Этот код создает ссылку на элемент textarea, а затем передает ее элементу textarea в строке 24.
useAutoSizeTextArea('title-input', textAreaRef.current, value);
Магия заключается в следующем: с помощью пользовательского хука useAutoSizeTextArea передается id, элемент textarea из textAreaRef, и, наконец, value.
Не стесняйтесь экспериментировать с примером, чтобы увидеть, как он динамически вычисляет высоту по мере изменения содержимого. Кроме того, попробуйте закомментировать строку номер 12, чтобы увидеть, как текстовая область становится вертикально прокручиваемой, а высота остается статичной.
Заключение
В этой статье я показал, как я решаю проблему динамической регулировки высоты элемента textarea на основе его содержимого, предотвращая необходимость вертикальной прокрутки в разделе заголовка страницы статьи OpenMetadata Knowledge.
На этом мы закончили эту тему. Спасибо, что прочитали.
Если вы нашли эту статью полезной, пожалуйста, поставьте лайк и поделитесь ею с другими. Если у вас есть вопросы, не стесняйтесь оставлять комментарии, и я постараюсь ответить на них.