В этом задании мы познакомимся с хуком useRef и создадим интерактивный чат с автоматической прокруткой и имитацией бота.
useRef - это хук для сохранения значений между рендерами без их перерисовки. Но чаще всего он используется для доступа к DOM элементам напрямую.
Представьте, что вам нужно управлять элементом как в обычном JavaScript - прокрутить страницу, установить фокус в поле, измерить размер. React обычно не даёт прямой доступ к DOM, но useRef позволяет получить ссылку на элемент:
const inputRef =useRef(null);<inputref={inputRef}/>// Теперь можно работать с элементом:inputRef.current.focus();// Установить фокус
Автоскролл в чате - частая задача. Когда приходит новое сообщение, окно должно прокручиваться вниз. Для этого создаём пустой div в конце списка:
const messagesEndRef =useRef(null);<divclassName="messages">{messages.map(msg=><div>{msg.text}</div>)}<divref={messagesEndRef}/>{/* Якорь для прокрутки */}</div>
Метод scrollIntoView() прокручивает страницу так, чтобы элемент был виден:
Оператор ?. (optional chaining) проверяет, что current не null, прежде чем вызывать метод.
Форматирование времени:
const time =newDate().toLocaleTimeString('ru-RU',{hour:'2-digit',minute:'2-digit'});// Результат: "14:35"
Имитация задержки с setTimeout:
setTimeout(()=>{// Код выполнится через 1.5 секундыaddBotMessage('Привет!');},1500);
Задание
Необходимо создать чат-интерфейс с автопрокруткой и имитацией бота. Создайте состояния: messages (массив сообщений, начальное значение INITIAL_MESSAGES), inputValue (текст в поле ввода, начальное ''), isTyping (печатает ли бот, начальное false). Создайте useRef с именем messagesEndRef для автоскролла. В useEffect с зависимостью [messages] вызывайте функцию scrollToBottom(), которая прокручивает к messagesEndRef методом scrollIntoView({ behavior: 'smooth' }). В функции sendMessage проверьте, что поле не пустое, создайте новое сообщение с текущим временем (используйте Date.now() для id и toLocaleTimeString() для времени), добавьте его в массив, очистите input. Опционально: установите isTyping в true, через setTimeout (1-2 секунды) добавьте случайный ответ бота из массива готовых фраз и установите isTyping в false. Отобразите все сообщения с разными классами для user ("message sent") и bot ("message received"). Покажите индикатор печатания когда isTyping === true. Заблокируйте кнопку отправки если поле пустое.