From d07861ffddbf151fc4e98940490e4348845bd491 Mon Sep 17 00:00:00 2001 From: Matvei Andrienko Date: Thu, 18 Jan 2024 10:43:17 +0100 Subject: [PATCH] feat: enable exhaustive-deps, but ignore all current errors (#2244) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 🎯 Goal Generally, `react-hooks/exhaustive-deps` eslint rule is very useful, but for historical reasons it's not always followed in our SDK. We can't fix every place this rule is violated, but at least we want to have exhaustive deps moving forward. This PR enable this eslint rule, but adds in-place ignores everywhere it's currently violated. That way we can make fixes incrementally, and benefit from improved linting moving forward. ### 🛠 Implementation details All changes were made automatically (and manually reviewed afterwards): 1. Enable `react-hooks/exhaustive-deps` 2. Export all linting errors to `lint.json`: ```sh npx eslint 'src/**/*.{js,ts,tsx,md}' -f json -o lint.json ``` 3. Use this script to add in-place ignores (adapted from https://stackoverflow.com/questions/60629026/is-there-a-way-to-programmatically-suppress-all-eslint-errors-on-a-line-by-line): ```js const json = require('./lint.json'); const fs = require('fs'); json.forEach(({ filePath, messages, source }) => { if (!source) { return; } const data = source.split('\n'); let offset = 1; const groupedMessages = messages.reduce((acc, next) => { const prevMessages = acc[next.line] ? acc[next.line] : []; const duplicateRuleForLine = prevMessages.find((message) => message.ruleId === next.ruleId); const applicableRule = next.ruleId === 'react-hooks/exhaustive-deps'; if (duplicateRuleForLine || !applicableRule) { return acc; } return { ...acc, [next.line]: [...prevMessages, next], }; }, {}); Object.entries(groupedMessages).forEach(([line, messages]) => { const ignore = `// eslint-disable-next-line ${messages.map(({ ruleId }) => ruleId).join(' ')}`; data.splice(line - offset, 0, ignore); offset--; }); const updated = data.join('\n'); fs.writeFile(filePath, updated, function (err) { if (err) return console.log(err); }); }); ``` --- .eslintrc.json | 4 ++-- src/components/Attachment/Attachment.tsx | 1 + src/components/Attachment/AttachmentContainer.tsx | 1 + src/components/Attachment/hooks/useAudioController.ts | 1 + src/components/Channel/Channel.tsx | 3 +++ src/components/Channel/__tests__/Channel.test.js | 1 + src/components/Channel/hooks/useCreateChannelStateContext.ts | 1 + src/components/Channel/hooks/useCreateTypingContext.ts | 1 + src/components/ChannelList/ChannelList.tsx | 3 +++ src/components/ChannelList/__tests__/ChannelList.test.js | 1 + .../ChannelList/hooks/useChannelDeletedListener.ts | 1 + src/components/ChannelList/hooks/useChannelHiddenListener.ts | 1 + .../ChannelList/hooks/useChannelTruncatedListener.ts | 1 + .../ChannelList/hooks/useChannelUpdatedListener.ts | 1 + .../ChannelList/hooks/useChannelVisibleListener.ts | 1 + .../ChannelList/hooks/useConnectionRecoveredListener.ts | 1 + src/components/ChannelList/hooks/useMessageNewListener.ts | 1 + .../hooks/useNotificationAddedToChannelListener.ts | 1 + .../ChannelList/hooks/useNotificationMessageNewListener.ts | 1 + .../hooks/useNotificationRemovedFromChannelListener.ts | 1 + src/components/ChannelList/hooks/usePaginatedChannels.ts | 2 ++ .../ChannelList/hooks/useUserPresenceChangedListener.ts | 1 + src/components/ChannelPreview/ChannelPreview.tsx | 2 ++ src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts | 1 + src/components/ChannelPreview/hooks/useIsChannelMuted.ts | 1 + src/components/ChannelSearch/SearchBar.tsx | 2 ++ src/components/ChannelSearch/SearchResults.tsx | 1 + src/components/ChannelSearch/hooks/useChannelSearch.ts | 5 +++++ src/components/Chat/hooks/useChat.ts | 2 ++ src/components/Chat/hooks/useCreateChatContext.ts | 1 + src/components/Gallery/ModalGallery.tsx | 1 + src/components/InfiniteScrollPaginator/InfiniteScroll.tsx | 1 + src/components/LoadMore/LoadMoreButton.tsx | 1 + src/components/LoadMore/LoadMorePaginator.tsx | 1 + src/components/Message/MessageText.tsx | 1 + src/components/Message/hooks/useReactionHandler.ts | 2 ++ src/components/MessageInput/MessageInputFlat.tsx | 1 + src/components/MessageInput/MessageInputSmall.tsx | 1 + .../MessageInput/__tests__/LinkPreviewList.test.js | 1 + src/components/MessageInput/__tests__/MessageInput.test.js | 1 + src/components/MessageInput/hooks/useAttachments.ts | 1 + .../MessageInput/hooks/useCreateMessageInputContext.ts | 1 + src/components/MessageInput/hooks/useFileUploads.ts | 3 +++ src/components/MessageInput/hooks/useImageUploads.ts | 2 ++ src/components/MessageInput/hooks/useLinkPreviews.ts | 3 +++ src/components/MessageInput/hooks/useMessageInputText.ts | 2 ++ src/components/MessageInput/hooks/usePasteHandler.ts | 1 + src/components/MessageInput/hooks/useUserTrigger.ts | 1 + src/components/MessageList/MessageList.tsx | 2 ++ src/components/MessageList/ScrollToBottomButton.tsx | 1 + src/components/MessageList/VirtualizedMessageList.tsx | 4 ++++ .../MessageList/hooks/MessageList/useEnrichedMessages.ts | 1 + .../MessageList/hooks/MessageList/useMessageListElements.tsx | 1 + .../hooks/MessageList/useMessageListScrollManager.ts | 1 + .../MessageList/hooks/MessageList/useScrollLocationLogic.tsx | 1 + .../hooks/VirtualizedMessageList/useGiphyPreview.ts | 1 + .../hooks/VirtualizedMessageList/usePrependMessagesCount.ts | 1 + .../VirtualizedMessageList/useScrollToBottomOnNewMessage.ts | 1 + .../VirtualizedMessageList/useShouldForceScrollToBottom.ts | 1 + src/components/Reactions/hooks/useProcessReactions.tsx | 3 +++ src/components/Thread/Thread.tsx | 1 + src/stories/attachment-sizing.stories.tsx | 1 + src/stories/navigate-long-message-lists.stories.tsx | 1 + 63 files changed, 89 insertions(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a34c81fad4..44bd41fe75 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -79,7 +79,7 @@ "max-classes-per-file": 0, "camelcase": 0, "react-hooks/rules-of-hooks": 1, - "react-hooks/exhaustive-deps": 0, + "react-hooks/exhaustive-deps": 1, "jest/prefer-inline-snapshots": 0, "jest/lowercase-name": 0, "jest/prefer-expect-assertions": 0, @@ -166,7 +166,7 @@ "@typescript-eslint/ban-ts-comment": 0, "@typescript-eslint/no-unused-vars": 1, "@typescript-eslint/no-var-requires": 0, - "react-hooks/exhaustive-deps": 0, + "react-hooks/exhaustive-deps": 1, "react-native/no-inline-styles": 0, "array-callback-return": 2, "arrow-body-style": 2, diff --git a/src/components/Attachment/Attachment.tsx b/src/components/Attachment/Attachment.tsx index 43efff9cbd..b50282e1d6 100644 --- a/src/components/Attachment/Attachment.tsx +++ b/src/components/Attachment/Attachment.tsx @@ -84,6 +84,7 @@ export const Attachment = < ) => { const { attachments } = props; + // eslint-disable-next-line react-hooks/exhaustive-deps const groupedAttachments = useMemo(() => renderGroupedAttachments(props), [attachments]); return ( diff --git a/src/components/Attachment/AttachmentContainer.tsx b/src/components/Attachment/AttachmentContainer.tsx index dcbb35b422..c1c21889c4 100644 --- a/src/components/Attachment/AttachmentContainer.tsx +++ b/src/components/Attachment/AttachmentContainer.tsx @@ -260,6 +260,7 @@ export const MediaContainer = < ); setAttachmentConfiguration(config); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [videoElement, videoAttachmentSizeHandler, attachment]); const content = ( diff --git a/src/components/Attachment/hooks/useAudioController.ts b/src/components/Attachment/hooks/useAudioController.ts index 6b8c58ff6b..9a36b286d9 100644 --- a/src/components/Attachment/hooks/useAudioController.ts +++ b/src/components/Attachment/hooks/useAudioController.ts @@ -43,6 +43,7 @@ export const useAudioController = () => { audioRef.current.play(); return () => { + // eslint-disable-next-line react-hooks/exhaustive-deps audioRef.current?.pause(); window.clearInterval(interval); diff --git a/src/components/Channel/Channel.tsx b/src/components/Channel/Channel.tsx index 4a5eecb3e9..a210be7078 100644 --- a/src/components/Channel/Channel.tsx +++ b/src/components/Channel/Channel.tsx @@ -567,6 +567,7 @@ const ChannelInner = < client.off('user.deleted', handleEvent); notificationTimeouts.forEach(clearTimeout); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ channel.cid, channelQueryOptions, @@ -987,6 +988,7 @@ const ChannelInner = < skipMessageDataMemoization, updateMessage, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [ channel.cid, deleteMessage, @@ -1046,6 +1048,7 @@ const ChannelInner = < TypingIndicator: props.TypingIndicator, VirtualMessage: props.VirtualMessage, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [props.reactionOptions], ); diff --git a/src/components/Channel/__tests__/Channel.test.js b/src/components/Channel/__tests__/Channel.test.js index f067d03fff..233eedf090 100644 --- a/src/components/Channel/__tests__/Channel.test.js +++ b/src/components/Channel/__tests__/Channel.test.js @@ -61,6 +61,7 @@ const CallbackEffectWithChannelContexts = ({ callback }) => { const channelActionContext = useChannelActionContext(); const componentContext = useComponentContext(); + // eslint-disable-next-line react-hooks/exhaustive-deps const channelContext = { ...channelStateContext, ...channelActionContext, diff --git a/src/components/Channel/hooks/useCreateChannelStateContext.ts b/src/components/Channel/hooks/useCreateChannelStateContext.ts index 8914abc2da..3756e4557b 100644 --- a/src/components/Channel/hooks/useCreateChannelStateContext.ts +++ b/src/components/Channel/hooks/useCreateChannelStateContext.ts @@ -136,6 +136,7 @@ export const useCreateChannelStateContext = < watcherCount, watchers, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [ channelId, debounceURLEnrichmentMs, diff --git a/src/components/Channel/hooks/useCreateTypingContext.ts b/src/components/Channel/hooks/useCreateTypingContext.ts index d5f9ebec3e..ee55dfe04c 100644 --- a/src/components/Channel/hooks/useCreateTypingContext.ts +++ b/src/components/Channel/hooks/useCreateTypingContext.ts @@ -16,6 +16,7 @@ export const useCreateTypingContext = < () => ({ typing, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [typingValue], ); diff --git a/src/components/ChannelList/ChannelList.tsx b/src/components/ChannelList/ChannelList.tsx index a5fd518e18..067d59c1e9 100644 --- a/src/components/ChannelList/ChannelList.tsx +++ b/src/components/ChannelList/ChannelList.tsx @@ -258,11 +258,13 @@ const UnMemoizedChannelList = < setSearchActive(true); } additionalChannelSearchProps?.onSearch?.(event); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const onSearchExit = useCallback(() => { setSearchActive(false); additionalChannelSearchProps?.onSearchExit?.(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const { channels, hasNextPage, loadNextPage, setChannels } = usePaginatedChannels( @@ -317,6 +319,7 @@ const UnMemoizedChannelList = < client.off('channel.deleted', handleEvent); client.off('channel.hidden', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [channel?.cid]); const renderChannel = (item: Channel) => { diff --git a/src/components/ChannelList/__tests__/ChannelList.test.js b/src/components/ChannelList/__tests__/ChannelList.test.js index 9ab5c23e37..6845b17c40 100644 --- a/src/components/ChannelList/__tests__/ChannelList.test.js +++ b/src/components/ChannelList/__tests__/ChannelList.test.js @@ -1700,6 +1700,7 @@ describe('ChannelList', () => { const { channels, setChannels } = useChannelListContext(); useEffect(() => { setChannelsFromOutside = setChannels; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return
{channelsToIdString(channels)}
; }; diff --git a/src/components/ChannelList/hooks/useChannelDeletedListener.ts b/src/components/ChannelList/hooks/useChannelDeletedListener.ts index 1140356653..61d1287887 100644 --- a/src/components/ChannelList/hooks/useChannelDeletedListener.ts +++ b/src/components/ChannelList/hooks/useChannelDeletedListener.ts @@ -40,5 +40,6 @@ export const useChannelDeletedListener = < return () => { client.off('channel.deleted', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useChannelHiddenListener.ts b/src/components/ChannelList/hooks/useChannelHiddenListener.ts index 8369f7851a..e27561d226 100644 --- a/src/components/ChannelList/hooks/useChannelHiddenListener.ts +++ b/src/components/ChannelList/hooks/useChannelHiddenListener.ts @@ -39,5 +39,6 @@ export const useChannelHiddenListener = < return () => { client.off('channel.hidden', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useChannelTruncatedListener.ts b/src/components/ChannelList/hooks/useChannelTruncatedListener.ts index 6b6715d085..e3b8e69a3b 100644 --- a/src/components/ChannelList/hooks/useChannelTruncatedListener.ts +++ b/src/components/ChannelList/hooks/useChannelTruncatedListener.ts @@ -35,5 +35,6 @@ export const useChannelTruncatedListener = < return () => { client.off('channel.truncated', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useChannelUpdatedListener.ts b/src/components/ChannelList/hooks/useChannelUpdatedListener.ts index 8215fd061a..3a59ccdcf2 100644 --- a/src/components/ChannelList/hooks/useChannelUpdatedListener.ts +++ b/src/components/ChannelList/hooks/useChannelUpdatedListener.ts @@ -50,5 +50,6 @@ export const useChannelUpdatedListener = < return () => { client.off('channel.updated', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useChannelVisibleListener.ts b/src/components/ChannelList/hooks/useChannelVisibleListener.ts index d7a07ef7ad..9b2dd507db 100644 --- a/src/components/ChannelList/hooks/useChannelVisibleListener.ts +++ b/src/components/ChannelList/hooks/useChannelVisibleListener.ts @@ -39,5 +39,6 @@ export const useChannelVisibleListener = < return () => { client.off('channel.visible', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useConnectionRecoveredListener.ts b/src/components/ChannelList/hooks/useConnectionRecoveredListener.ts index 065abe813e..b71d30898e 100644 --- a/src/components/ChannelList/hooks/useConnectionRecoveredListener.ts +++ b/src/components/ChannelList/hooks/useConnectionRecoveredListener.ts @@ -23,5 +23,6 @@ export const useConnectionRecoveredListener = < return () => { client.off('connection.recovered', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); }; diff --git a/src/components/ChannelList/hooks/useMessageNewListener.ts b/src/components/ChannelList/hooks/useMessageNewListener.ts index b2b9b05f95..1d1d2bfe71 100644 --- a/src/components/ChannelList/hooks/useMessageNewListener.ts +++ b/src/components/ChannelList/hooks/useMessageNewListener.ts @@ -47,5 +47,6 @@ export const useMessageNewListener = < return () => { client.off('message.new', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [lockChannelOrder]); }; diff --git a/src/components/ChannelList/hooks/useNotificationAddedToChannelListener.ts b/src/components/ChannelList/hooks/useNotificationAddedToChannelListener.ts index b2d075b65c..fc338c048a 100644 --- a/src/components/ChannelList/hooks/useNotificationAddedToChannelListener.ts +++ b/src/components/ChannelList/hooks/useNotificationAddedToChannelListener.ts @@ -47,5 +47,6 @@ export const useNotificationAddedToChannelListener = < return () => { client.off('notification.added_to_channel', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useNotificationMessageNewListener.ts b/src/components/ChannelList/hooks/useNotificationMessageNewListener.ts index 94a65720dc..9b034e2ebf 100644 --- a/src/components/ChannelList/hooks/useNotificationMessageNewListener.ts +++ b/src/components/ChannelList/hooks/useNotificationMessageNewListener.ts @@ -40,5 +40,6 @@ export const useNotificationMessageNewListener = < return () => { client.off('notification.message_new', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/useNotificationRemovedFromChannelListener.ts b/src/components/ChannelList/hooks/useNotificationRemovedFromChannelListener.ts index ce013da9b8..92ce342621 100644 --- a/src/components/ChannelList/hooks/useNotificationRemovedFromChannelListener.ts +++ b/src/components/ChannelList/hooks/useNotificationRemovedFromChannelListener.ts @@ -33,5 +33,6 @@ export const useNotificationRemovedFromChannelListener = < return () => { client.off('notification.removed_from_channel', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [customHandler]); }; diff --git a/src/components/ChannelList/hooks/usePaginatedChannels.ts b/src/components/ChannelList/hooks/usePaginatedChannels.ts index ec955b11d0..abb35384ca 100644 --- a/src/components/ChannelList/hooks/usePaginatedChannels.ts +++ b/src/components/ChannelList/hooks/usePaginatedChannels.ts @@ -42,6 +42,7 @@ export const usePaginatedChannels = < const filterString = useMemo(() => JSON.stringify(filters), [filters]); const sortString = useMemo(() => JSON.stringify(sort), [sort]); + // eslint-disable-next-line react-hooks/exhaustive-deps const queryChannels = async (queryType?: string) => { setError(null); @@ -113,6 +114,7 @@ export const usePaginatedChannels = < useEffect(() => { queryChannels('reload'); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [filterString, sortString]); return { diff --git a/src/components/ChannelList/hooks/useUserPresenceChangedListener.ts b/src/components/ChannelList/hooks/useUserPresenceChangedListener.ts index 1b3ec94e39..c8e134b2f8 100644 --- a/src/components/ChannelList/hooks/useUserPresenceChangedListener.ts +++ b/src/components/ChannelList/hooks/useUserPresenceChangedListener.ts @@ -36,5 +36,6 @@ export const useUserPresenceChangedListener = < return () => { client.off('user.presence.changed', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); }; diff --git a/src/components/ChannelPreview/ChannelPreview.tsx b/src/components/ChannelPreview/ChannelPreview.tsx index ac5d707de5..6cdadc19b6 100644 --- a/src/components/ChannelPreview/ChannelPreview.tsx +++ b/src/components/ChannelPreview/ChannelPreview.tsx @@ -92,6 +92,7 @@ export const ChannelPreview = < client.on('notification.mark_read', handleEvent); return () => client.off('notification.mark_read', handleEvent); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const refreshUnreadCount = useCallback(() => { @@ -119,6 +120,7 @@ export const ChannelPreview = < channel.off('message.updated', handleEvent); channel.off('message.deleted', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [refreshUnreadCount, channelUpdateCount]); if (!Preview) return null; diff --git a/src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts b/src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts index 76c1b56dc2..bd179fd212 100644 --- a/src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts +++ b/src/components/ChannelPreview/hooks/useChannelPreviewInfo.ts @@ -41,6 +41,7 @@ export const useChannelPreviewInfo = < return () => { client.off('user.updated', handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return { diff --git a/src/components/ChannelPreview/hooks/useIsChannelMuted.ts b/src/components/ChannelPreview/hooks/useIsChannelMuted.ts index 20371182cc..cda462f77e 100644 --- a/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +++ b/src/components/ChannelPreview/hooks/useIsChannelMuted.ts @@ -20,6 +20,7 @@ export const useIsChannelMuted = < client.on('notification.channel_mutes_updated', handleEvent); return () => client.off('notification.channel_mutes_updated', handleEvent); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [muted]); return muted; diff --git a/src/components/ChannelSearch/SearchBar.tsx b/src/components/ChannelSearch/SearchBar.tsx index 40aa584900..d8f4c4b9e8 100644 --- a/src/components/ChannelSearch/SearchBar.tsx +++ b/src/components/ChannelSearch/SearchBar.tsx @@ -130,11 +130,13 @@ export const SearchBar = (props: SearchBarProps) => { props.inputRef.current?.removeEventListener('focus', handleFocus); props.inputRef.current?.addEventListener('blur', handleBlur); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const handleClearClick = useCallback(() => { exitSearch(); inputProps.inputRef.current?.focus(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const closeAppMenu = useCallback(() => setMenuIsOpen(false), []); diff --git a/src/components/ChannelSearch/SearchResults.tsx b/src/components/ChannelSearch/SearchResults.tsx index 04c2e04ec6..9cdd24fd86 100644 --- a/src/components/ChannelSearch/SearchResults.tsx +++ b/src/components/ChannelSearch/SearchResults.tsx @@ -227,6 +227,7 @@ export const SearchResults = < } } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [focusedResult], ); diff --git a/src/components/ChannelSearch/hooks/useChannelSearch.ts b/src/components/ChannelSearch/hooks/useChannelSearch.ts index 916b563ec4..e06c62dfa8 100644 --- a/src/components/ChannelSearch/hooks/useChannelSearch.ts +++ b/src/components/ChannelSearch/hooks/useChannelSearch.ts @@ -161,6 +161,7 @@ export const useChannelSearch = < document.addEventListener('click', clickListener); return () => document.removeEventListener('click', clickListener); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [disabled, inputIsFocused, query, exitSearch, clearSearchOnClickOutside]); useEffect(() => { @@ -172,8 +173,10 @@ export const useChannelSearch = < inputRef.current.addEventListener('keydown', handleKeyDown); return () => { + // eslint-disable-next-line react-hooks/exhaustive-deps inputRef.current?.removeEventListener('keydown', handleKeyDown); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [disabled]); const selectResult = useCallback( @@ -206,6 +209,7 @@ export const useChannelSearch = < exitSearch(); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [clearSearchOnClickOutside, client, exitSearch, onSelectResult, setActiveChannel, setChannels], ); @@ -264,6 +268,7 @@ export const useChannelSearch = < [client, searchForChannels, searchQueryParams], ); + // eslint-disable-next-line react-hooks/exhaustive-deps const scheduleGetChannels = useCallback(debounce(getChannels, searchDebounceIntervalMs), [ getChannels, searchDebounceIntervalMs, diff --git a/src/components/Chat/hooks/useChat.ts b/src/components/Chat/hooks/useChat.ts index 2f949f2d66..280e620bdc 100644 --- a/src/components/Chat/hooks/useChat.ts +++ b/src/components/Chat/hooks/useChat.ts @@ -75,6 +75,7 @@ export const useChat = < client.on('notification.mutes_updated', handleEvent); return () => client.off('notification.mutes_updated', handleEvent); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [clientMutes?.length]); useEffect(() => { @@ -97,6 +98,7 @@ export const useChat = < userLanguage: userLanguage || defaultLanguage, }); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [i18nInstance]); const setActiveChannel = useCallback( diff --git a/src/components/Chat/hooks/useCreateChatContext.ts b/src/components/Chat/hooks/useCreateChatContext.ts index 3986ff2539..4cabaa9504 100644 --- a/src/components/Chat/hooks/useCreateChatContext.ts +++ b/src/components/Chat/hooks/useCreateChatContext.ts @@ -51,6 +51,7 @@ export const useCreateChatContext = < themeVersion, useImageFlagEmojisOnWindows, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [ channelCid, channelsQueryError, diff --git a/src/components/Gallery/ModalGallery.tsx b/src/components/Gallery/ModalGallery.tsx index 962d9e2bb9..dd55e040f5 100644 --- a/src/components/Gallery/ModalGallery.tsx +++ b/src/components/Gallery/ModalGallery.tsx @@ -43,6 +43,7 @@ export const ModalGallery = < source: imageSrc, }; }), + // eslint-disable-next-line react-hooks/exhaustive-deps [images], ); diff --git a/src/components/InfiniteScrollPaginator/InfiniteScroll.tsx b/src/components/InfiniteScrollPaginator/InfiniteScroll.tsx index aad3c278f7..156c4f1e93 100644 --- a/src/components/InfiniteScrollPaginator/InfiniteScroll.tsx +++ b/src/components/InfiniteScrollPaginator/InfiniteScroll.tsx @@ -123,6 +123,7 @@ export const InfiniteScroll = (props: PropsWithChildren) => ], 'InfiniteScroll', ); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useLayoutEffect(() => { diff --git a/src/components/LoadMore/LoadMoreButton.tsx b/src/components/LoadMore/LoadMoreButton.tsx index 593de4761e..d589bedca8 100644 --- a/src/components/LoadMore/LoadMoreButton.tsx +++ b/src/components/LoadMore/LoadMoreButton.tsx @@ -28,6 +28,7 @@ const UnMemoizedLoadMoreButton = ({ useEffect(() => { deprecationAndReplacementWarning([[{ refreshing }, { isLoading }]], 'LoadMoreButton'); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/src/components/LoadMore/LoadMorePaginator.tsx b/src/components/LoadMore/LoadMorePaginator.tsx index 5a78aa8de3..c789fa984a 100644 --- a/src/components/LoadMore/LoadMorePaginator.tsx +++ b/src/components/LoadMore/LoadMorePaginator.tsx @@ -25,6 +25,7 @@ export const UnMemoizedLoadMorePaginator = (props: PropsWithChildren { deprecationAndReplacementWarning([[{ refreshing }, { isLoading }]], 'LoadMorePaginator'); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/src/components/Message/MessageText.tsx b/src/components/Message/MessageText.tsx index 4f806d836b..270ffd61f1 100644 --- a/src/components/Message/MessageText.tsx +++ b/src/components/Message/MessageText.tsx @@ -57,6 +57,7 @@ const UnMemoizedMessageTextComponent = < const messageTextToRender = message.i18n?.[`${userLanguage}_text` as `${TranslationLanguages}_text`] || message.text; + // eslint-disable-next-line react-hooks/exhaustive-deps const messageText = useMemo(() => renderText(messageTextToRender, message.mentioned_users), [ message.mentioned_users, messageTextToRender, diff --git a/src/components/Message/hooks/useReactionHandler.ts b/src/components/Message/hooks/useReactionHandler.ts index 6381982102..e8dd403d8c 100644 --- a/src/components/Message/hooks/useReactionHandler.ts +++ b/src/components/Message/hooks/useReactionHandler.ts @@ -63,6 +63,7 @@ export const useReactionHandler = < reaction_scores: newReactionCounts, } as StreamMessage; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [client.user, client.userID], ); @@ -163,6 +164,7 @@ export const useReactionClick = < setShowDetailedReactions(false); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [setShowDetailedReactions, reactionSelectorRef], ); diff --git a/src/components/MessageInput/MessageInputFlat.tsx b/src/components/MessageInput/MessageInputFlat.tsx index a386f2b90f..07a6c439b7 100644 --- a/src/components/MessageInput/MessageInputFlat.tsx +++ b/src/components/MessageInput/MessageInputFlat.tsx @@ -54,6 +54,7 @@ export const MessageInputFlat = < channel?.off('message.deleted', handleQuotedMessageUpdate); channel?.off('message.updated', handleQuotedMessageUpdate); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [channel, quotedMessage]); return themeVersion === '2' ? ( diff --git a/src/components/MessageInput/MessageInputSmall.tsx b/src/components/MessageInput/MessageInputSmall.tsx index 2c1d59c881..5269a3e748 100644 --- a/src/components/MessageInput/MessageInputSmall.tsx +++ b/src/components/MessageInput/MessageInputSmall.tsx @@ -81,6 +81,7 @@ export const MessageInputSmall = < channel?.off('message.deleted', handleQuotedMessageUpdate); channel?.off('message.updated', handleQuotedMessageUpdate); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [channel, quotedMessage]); return (
diff --git a/src/components/MessageInput/__tests__/LinkPreviewList.test.js b/src/components/MessageInput/__tests__/LinkPreviewList.test.js index 0ae3d342b5..5061c6ea03 100644 --- a/src/components/MessageInput/__tests__/LinkPreviewList.test.js +++ b/src/components/MessageInput/__tests__/LinkPreviewList.test.js @@ -84,6 +84,7 @@ const ActiveChannelSetter = ({ activeChannel }) => { const { setActiveChannel } = useChatContext(); useEffect(() => { setActiveChannel(activeChannel); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeChannel]); return null; }; diff --git a/src/components/MessageInput/__tests__/MessageInput.test.js b/src/components/MessageInput/__tests__/MessageInput.test.js index d6544d6ee1..ce3bf842bc 100644 --- a/src/components/MessageInput/__tests__/MessageInput.test.js +++ b/src/components/MessageInput/__tests__/MessageInput.test.js @@ -101,6 +101,7 @@ const ActiveChannelSetter = ({ activeChannel }) => { const { setActiveChannel } = useChatContext(); useEffect(() => { setActiveChannel(activeChannel); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeChannel]); return null; }; diff --git a/src/components/MessageInput/hooks/useAttachments.ts b/src/components/MessageInput/hooks/useAttachments.ts index f4db818bac..c23a343f88 100644 --- a/src/components/MessageInput/hooks/useAttachments.ts +++ b/src/components/MessageInput/hooks/useAttachments.ts @@ -77,6 +77,7 @@ export const useAttachments = < textareaRef?.current?.focus(); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [maxFilesLeft, noFiles], ); diff --git a/src/components/MessageInput/hooks/useCreateMessageInputContext.ts b/src/components/MessageInput/hooks/useCreateMessageInputContext.ts index 50f4796629..bae9a61c6e 100644 --- a/src/components/MessageInput/hooks/useCreateMessageInputContext.ts +++ b/src/components/MessageInput/hooks/useCreateMessageInputContext.ts @@ -142,6 +142,7 @@ export const useCreateMessageInputContext = < uploadNewFiles, useMentionsTransliteration, }), + // eslint-disable-next-line react-hooks/exhaustive-deps [ cancelURLEnrichment, cooldownInterval, diff --git a/src/components/MessageInput/hooks/useFileUploads.ts b/src/components/MessageInput/hooks/useFileUploads.ts index bfbfa5da51..7187553de4 100644 --- a/src/components/MessageInput/hooks/useFileUploads.ts +++ b/src/components/MessageInput/hooks/useFileUploads.ts @@ -31,11 +31,13 @@ export const useFileUploads = < const uploadFile = useCallback((id: string) => { dispatch({ id, state: 'uploading', type: 'setFileUpload' }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const removeFile = useCallback((id: string) => { // TODO: cancel upload if still uploading dispatch({ id, type: 'removeFileUpload' }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { @@ -105,6 +107,7 @@ export const useFileUploads = < url: response.file, }); })(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [fileUploads, channel, doFileUploadRequest, errorHandler, removeFile]); return { diff --git a/src/components/MessageInput/hooks/useImageUploads.ts b/src/components/MessageInput/hooks/useImageUploads.ts index 7d614296ca..6d22b3de4d 100644 --- a/src/components/MessageInput/hooks/useImageUploads.ts +++ b/src/components/MessageInput/hooks/useImageUploads.ts @@ -32,6 +32,7 @@ export const useImageUploads = < const removeImage = useCallback((id: string) => { dispatch({ id, type: 'removeImageUpload' }); // TODO: cancel upload if still uploading + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const uploadImage = useCallback( @@ -107,6 +108,7 @@ export const useImageUploads = < url: response.file, }); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [imageUploads, channel, doImageUploadRequest, errorHandler, removeImage], ); diff --git a/src/components/MessageInput/hooks/useLinkPreviews.ts b/src/components/MessageInput/hooks/useLinkPreviews.ts index c9255ce84e..5f37dd2d6b 100644 --- a/src/components/MessageInput/hooks/useLinkPreviews.ts +++ b/src/components/MessageInput/hooks/useLinkPreviews.ts @@ -74,9 +74,11 @@ export const useLinkPreviews = < type: 'setLinkPreviews', }); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [onLinkPreviewDismissed], ); + // eslint-disable-next-line react-hooks/exhaustive-deps const findAndEnqueueURLsToEnrich = useCallback( debounce( (text: string, mode = SetLinkPreviewMode.SET) => { @@ -165,6 +167,7 @@ export const useLinkPreviews = < }); }); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [shouldDiscardEnrichQueries, linkPreviews]); return { diff --git a/src/components/MessageInput/hooks/useMessageInputText.ts b/src/components/MessageInput/hooks/useMessageInputText.ts index 22fb33f43f..e39842e03d 100644 --- a/src/components/MessageInput/hooks/useMessageInputText.ts +++ b/src/components/MessageInput/hooks/useMessageInputText.ts @@ -66,6 +66,7 @@ export const useMessageInputText = < type: 'setText', }); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [additionalTextareaProps, newCursorPosition, textareaRef], ); @@ -97,6 +98,7 @@ export const useMessageInputText = < logChatPromiseExecution(channel.keystroke(parent?.id), 'start typing event'); } }, + // eslint-disable-next-line react-hooks/exhaustive-deps [channel, findAndEnqueueURLsToEnrich, parent, publishTypingEvent], ); diff --git a/src/components/MessageInput/hooks/usePasteHandler.ts b/src/components/MessageInput/hooks/usePasteHandler.ts index 5a648cebf5..5849331e68 100644 --- a/src/components/MessageInput/hooks/usePasteHandler.ts +++ b/src/components/MessageInput/hooks/usePasteHandler.ts @@ -53,6 +53,7 @@ export const usePasteHandler = ( } })(clipboardEvent); }, + // eslint-disable-next-line react-hooks/exhaustive-deps [insertText, uploadNewFiles], ); diff --git a/src/components/MessageInput/hooks/useUserTrigger.ts b/src/components/MessageInput/hooks/useUserTrigger.ts index 6e7872e66e..b1e9339f81 100644 --- a/src/components/MessageInput/hooks/useUserTrigger.ts +++ b/src/components/MessageInput/hooks/useUserTrigger.ts @@ -63,6 +63,7 @@ export const useUserTrigger = < return Object.values(uniqueUsers); }, [members, watchers]); + // eslint-disable-next-line react-hooks/exhaustive-deps const queryMembersThrottled = useCallback( throttle( async (query: string, onReady: (users: UserResponse[]) => void) => { diff --git a/src/components/MessageList/MessageList.tsx b/src/components/MessageList/MessageList.tsx index d5f952f457..98713e1aa5 100644 --- a/src/components/MessageList/MessageList.tsx +++ b/src/components/MessageList/MessageList.tsx @@ -169,6 +169,7 @@ const MessageListWithContext = < } else { scrollToBottom(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [scrollToBottom, hasMoreNewer]); React.useLayoutEffect(() => { @@ -176,6 +177,7 @@ const MessageListWithContext = < const element = ulElement?.querySelector(`[data-message-id='${highlightedMessageId}']`); element?.scrollIntoView({ block: 'center' }); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [highlightedMessageId]); const showEmptyStateIndicator = elements.length === 0 && !threadList; diff --git a/src/components/MessageList/ScrollToBottomButton.tsx b/src/components/MessageList/ScrollToBottomButton.tsx index 4785c44ee7..8255f4a00e 100644 --- a/src/components/MessageList/ScrollToBottomButton.tsx +++ b/src/components/MessageList/ScrollToBottomButton.tsx @@ -51,6 +51,7 @@ const UnMemoizedScrollToBottomButton = ( return () => { client.off(observedEvent, handleEvent); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [activeChannel, isMessageListScrolledToBottom, observedEvent, replyCount, thread]); useEffect(() => { diff --git a/src/components/MessageList/VirtualizedMessageList.tsx b/src/components/MessageList/VirtualizedMessageList.tsx index 535e0904b8..00fa4f9cc5 100644 --- a/src/components/MessageList/VirtualizedMessageList.tsx +++ b/src/components/MessageList/VirtualizedMessageList.tsx @@ -231,6 +231,7 @@ const VirtualizedMessageListWithContext = < setGiphyPreviewMessage, userId: client.userID || '', }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ disableDateSeparator, hideDeletedMessages, @@ -267,6 +268,7 @@ const VirtualizedMessageListWithContext = < return acc; }, {}), // processedMessages were incorrectly rebuilt with a new object identity at some point, hence the .length usage + // eslint-disable-next-line react-hooks/exhaustive-deps [processedMessages.length, shouldGroupByUser, groupStylesFn], ); @@ -289,6 +291,7 @@ const VirtualizedMessageListWithContext = < } setNewMessagesNotification(false); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ virtuoso, processedMessages, @@ -354,6 +357,7 @@ const VirtualizedMessageListWithContext = < virtuoso.current?.scrollToIndex({ align: 'center', index }); } } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [highlightedMessageId]); if (!processedMessages) return null; diff --git a/src/components/MessageList/hooks/MessageList/useEnrichedMessages.ts b/src/components/MessageList/hooks/MessageList/useEnrichedMessages.ts index 1c5ddeb39f..6fe012f86e 100644 --- a/src/components/MessageList/hooks/MessageList/useEnrichedMessages.ts +++ b/src/components/MessageList/hooks/MessageList/useEnrichedMessages.ts @@ -75,6 +75,7 @@ export const useEnrichedMessages = < if (style) acc[message.id] = style; return acc; }, {}), + // eslint-disable-next-line react-hooks/exhaustive-deps [messagesWithDates, noGroupByUser], ); diff --git a/src/components/MessageList/hooks/MessageList/useMessageListElements.tsx b/src/components/MessageList/hooks/MessageList/useMessageListElements.tsx index f2abb50245..d6c87c0faf 100644 --- a/src/components/MessageList/hooks/MessageList/useMessageListElements.tsx +++ b/src/components/MessageList/hooks/MessageList/useMessageListElements.tsx @@ -128,6 +128,7 @@ export const useMessageListElements = < ); }), + // eslint-disable-next-line react-hooks/exhaustive-deps [ enrichedMessages, internalMessageProps, diff --git a/src/components/MessageList/hooks/MessageList/useMessageListScrollManager.ts b/src/components/MessageList/hooks/MessageList/useMessageListScrollManager.ts index ac13e0f2bd..c4c7d74edb 100644 --- a/src/components/MessageList/hooks/MessageList/useMessageListScrollManager.ts +++ b/src/components/MessageList/hooks/MessageList/useMessageListScrollManager.ts @@ -91,6 +91,7 @@ export function useMessageListScrollManager< messages.current = newMessages; measures.current = newMeasures; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [measures, messages, params.messages]); return (scrollTopValue: number) => { diff --git a/src/components/MessageList/hooks/MessageList/useScrollLocationLogic.tsx b/src/components/MessageList/hooks/MessageList/useScrollLocationLogic.tsx index 1058e3dbb2..c4d2b808bb 100644 --- a/src/components/MessageList/hooks/MessageList/useScrollLocationLogic.tsx +++ b/src/components/MessageList/hooks/MessageList/useScrollLocationLogic.tsx @@ -56,6 +56,7 @@ export const useScrollLocationLogic = < setWrapperRect(listElement.getBoundingClientRect()); scrollToBottom(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [listElement, hasMoreNewer]); const updateScrollTop = useMessageListScrollManager({ diff --git a/src/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.ts b/src/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.ts index 63aede77d8..e2bc3de573 100644 --- a/src/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.ts +++ b/src/components/MessageList/hooks/VirtualizedMessageList/useGiphyPreview.ts @@ -30,6 +30,7 @@ export const useGiphyPreview = < if (separateGiphyPreview) client.on('message.new', handleEvent); return () => client.off('message.new', handleEvent); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [separateGiphyPreview]); return { giphyPreviewMessage, setGiphyPreviewMessage }; diff --git a/src/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.ts b/src/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.ts index 4f64a93bc6..726124b248 100644 --- a/src/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.ts +++ b/src/components/MessageList/hooks/VirtualizedMessageList/usePrependMessagesCount.ts @@ -72,6 +72,7 @@ export function usePrependedMessagesCount< return 0; // TODO: there's a bug here, the messages prop is the same array instance (something mutates it) // that's why the second dependency is necessary + // eslint-disable-next-line react-hooks/exhaustive-deps }, [firstRealMessageIndex, messages, messages?.length]); return numItemsPrepended; diff --git a/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts b/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts index 450c3ec973..b1f14d79ed 100644 --- a/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts +++ b/src/components/MessageList/hooks/VirtualizedMessageList/useScrollToBottomOnNewMessage.ts @@ -54,5 +54,6 @@ export const useScrollToBottomOnNewMessage = < window.removeEventListener('focus', scrollToBottomIfConfigured); window.removeEventListener('blur', resetNewMessagesReceivedInBackground); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [scrollToBottomIfConfigured]); }; diff --git a/src/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.ts b/src/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.ts index ae0aa56fd4..11103b60f9 100644 --- a/src/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.ts +++ b/src/components/MessageList/hooks/VirtualizedMessageList/useShouldForceScrollToBottom.ts @@ -30,6 +30,7 @@ export function useShouldForceScrollToBottom< initialFocusRegistered.current = true; recheckForNewOwnMessage(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, [messages, messages?.length]); return recheckForNewOwnMessage; diff --git a/src/components/Reactions/hooks/useProcessReactions.tsx b/src/components/Reactions/hooks/useProcessReactions.tsx index bb935a726f..193cc7be26 100644 --- a/src/components/Reactions/hooks/useProcessReactions.tsx +++ b/src/components/Reactions/hooks/useProcessReactions.tsx @@ -30,8 +30,11 @@ export const useProcessReactions = < ); const reactionOptions = propReactionOptions ?? contextReactionOptions; + // eslint-disable-next-line react-hooks/exhaustive-deps const latestReactions = propReactions || message.latest_reactions || []; + // eslint-disable-next-line react-hooks/exhaustive-deps const ownReactions = propOwnReactions || message?.own_reactions || []; + // eslint-disable-next-line react-hooks/exhaustive-deps const reactionCounts = propReactionCounts || message.reaction_counts || {}; const iHaveReactedWithReaction = useCallback( diff --git a/src/components/Thread/Thread.tsx b/src/components/Thread/Thread.tsx index 2fe58fdeb0..606119b7bc 100644 --- a/src/components/Thread/Thread.tsx +++ b/src/components/Thread/Thread.tsx @@ -128,6 +128,7 @@ const ThreadInner = < // FIXME: integrators can customize channel query options but cannot customize channel.getReplies() options loadMoreThread(); } + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); if (!thread) return null; diff --git a/src/stories/attachment-sizing.stories.tsx b/src/stories/attachment-sizing.stories.tsx index ec8f900e04..437a66a515 100644 --- a/src/stories/attachment-sizing.stories.tsx +++ b/src/stories/attachment-sizing.stories.tsx @@ -110,6 +110,7 @@ const SetThreadOpen = () => { const [lastMsg] = messages.slice(-1); if (lastMsg) openThread(lastMsg, { preventDefault: () => null } as any); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [messages]); return null; diff --git a/src/stories/navigate-long-message-lists.stories.tsx b/src/stories/navigate-long-message-lists.stories.tsx index e9aeb51988..ac1c478710 100644 --- a/src/stories/navigate-long-message-lists.stories.tsx +++ b/src/stories/navigate-long-message-lists.stories.tsx @@ -110,6 +110,7 @@ const SetThreadOpen = () => { const [lastMsg] = messages.slice(-1); if (lastMsg) openThread(lastMsg, { preventDefault: () => null } as any); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [messages]); return null;