From 8980016e430d3cf53e88efa20b19a3381ab597c3 Mon Sep 17 00:00:00 2001 From: Anton Arnautov <43254280+arnautov-anton@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:50:38 +0200 Subject: [PATCH] refactor: useScrollToBottomOnNewMessage hook (#2532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 🎯 Goal Refactor `useScrollToBottomOnNewMessage` hook using `useRef`. --- .../useScrollToBottomOnNewMessage.ts | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts b/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts index b1f14d79ed..712040a2e3 100644 --- a/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts +++ b/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts @@ -1,11 +1,10 @@ -import React, { useCallback, useEffect } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { StreamMessage } from '../../../../context'; import { DefaultStreamChatGenerics } from '../../../../types/types'; type UseScrollToBottomOnNewMessageParams< StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics > = { - /** */ scrollToBottom: () => void; messages?: StreamMessage[]; /** When `true`, the list will scroll to the latest message when the window regains focus */ @@ -19,41 +18,43 @@ export const useScrollToBottomOnNewMessage = < scrollToBottom, scrollToLatestMessageOnFocus, }: UseScrollToBottomOnNewMessageParams) => { - const [newMessagesReceivedInBackground, setNewMessagesReceivedInBackground] = React.useState( - false, - ); + const [newMessagesReceivedInBackground, setNewMessagesReceivedInBackground] = useState(false); - const resetNewMessagesReceivedInBackground = useCallback(() => { - setNewMessagesReceivedInBackground(false); - }, []); + const scrollToBottomIfConfigured = useRef<(e: Event) => void>(); + + scrollToBottomIfConfigured.current = (event: Event) => { + if ( + !scrollToLatestMessageOnFocus || + !newMessagesReceivedInBackground || + event.target !== window + ) { + return; + } + + setTimeout(scrollToBottom, 100); + }; useEffect(() => { setNewMessagesReceivedInBackground(true); }, [messages]); - const scrollToBottomIfConfigured = useCallback( - (event: Event) => { - if ( - !scrollToLatestMessageOnFocus || - !newMessagesReceivedInBackground || - event.target !== window - ) - return; - setTimeout(scrollToBottom, 100); - }, - [scrollToLatestMessageOnFocus, scrollToBottom, newMessagesReceivedInBackground], - ); - useEffect(() => { + const handleFocus = (event: Event) => { + scrollToBottomIfConfigured.current?.(event); + }; + + const handleBlur = () => { + setNewMessagesReceivedInBackground(false); + }; + if (typeof window !== 'undefined') { - window.addEventListener('focus', scrollToBottomIfConfigured); - window.addEventListener('blur', resetNewMessagesReceivedInBackground); + window.addEventListener('focus', handleFocus); + window.addEventListener('blur', handleBlur); } return () => { - window.removeEventListener('focus', scrollToBottomIfConfigured); - window.removeEventListener('blur', resetNewMessagesReceivedInBackground); + window.removeEventListener('focus', handleFocus); + window.removeEventListener('blur', handleBlur); }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [scrollToBottomIfConfigured]); + }, []); };