From 568b23b6fe1953dbc2104573606113f19999487f Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 28 Feb 2023 18:43:28 +0100 Subject: [PATCH] [dev] Define custom static dependencies (#2462) --- .eslintrc | 12 ++++++++++-- package-lock.json | 7 +++++++ package.json | 1 + .../calls/group/GroupCallParticipantMenu.tsx | 2 +- src/components/left/main/StatusButton.tsx | 1 + src/components/left/search/AudioResults.tsx | 2 +- src/components/left/search/ChatMessageResults.tsx | 2 +- src/components/left/search/ChatResults.tsx | 2 +- src/components/left/search/FileResults.tsx | 2 +- src/components/left/search/LinkResults.tsx | 2 +- src/components/left/search/MediaResults.tsx | 2 +- src/components/main/ConfettiContainer.tsx | 2 +- src/components/middle/MessageList.tsx | 4 ++-- src/components/middle/composer/Composer.tsx | 4 ++-- src/components/middle/composer/hooks/useDraft.ts | 6 +++--- src/components/middle/composer/hooks/useEditing.ts | 2 +- .../middle/composer/hooks/useInlineBotTooltip.ts | 2 +- src/components/middle/hooks/useScrollHooks.ts | 2 +- src/components/right/RightColumn.tsx | 2 +- src/components/right/hooks/useAsyncRendering.ts | 4 ++-- src/components/ui/InfiniteScroll.tsx | 2 +- src/hooks/useAsync.ts | 2 +- src/hooks/useAsyncResolvers.ts | 4 ++-- src/hooks/useAudioPlayer.ts | 2 +- src/hooks/useBlurSync.ts | 2 +- src/hooks/useDebouncedCallback.ts | 2 +- src/hooks/useDebouncedMemo.ts | 2 +- src/hooks/useDerivedSignal.ts | 4 ++-- src/hooks/useDerivedState.ts | 4 ++-- src/hooks/useEffectOnce.ts | 2 +- src/hooks/useEffectWithPrevDeps.ts | 2 +- src/hooks/useIntersectionObserver.ts | 2 +- src/hooks/useLayoutEffectWithPrevDeps.ts | 2 +- src/hooks/useReducer.ts | 2 +- src/hooks/useRunDebounced.ts | 2 +- src/hooks/useRunThrottled.ts | 2 +- src/hooks/useThrottledCallback.ts | 2 +- src/hooks/useVideoCleanup.ts | 2 +- src/lib/teact/teact.ts | 4 ++-- 39 files changed, 63 insertions(+), 46 deletions(-) diff --git a/.eslintrc b/.eslintrc index bc91cf62e..3f6a521b3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,6 +10,7 @@ "no-async-without-await", "teactn", "no-null", + "react-hooks-static-deps", "eslint-multitab-tt" ], "rules": { @@ -40,10 +41,17 @@ "no-console": "error", "semi": "error", "no-implicit-coercion": "error", - "react-hooks/exhaustive-deps": [ + "react-hooks/exhaustive-deps": "off", + "react-hooks-static-deps/exhaustive-deps": [ "error", { - "additionalHooks": "(useSyncEffect|useAsync|useDebouncedCallback|useThrottledCallback|useEffectWithPrevDeps|useLayoutEffectWithPrevDeps|useDerivedState|useDerivedSignal|useThrottledResolver|useDebouncedResolver)$" + "additionalHooks": "(useSyncEffect|useAsync|useDebouncedCallback|useThrottledCallback|useEffectWithPrevDeps|useLayoutEffectWithPrevDeps|useDerivedState|useDerivedSignal|useThrottledResolver|useDebouncedResolver)$", + "staticHooks": { + "getActions": true, + "useFlag": [false, true, true], + "useForceUpdate": true, + "useReducer": [false, true] + } } ], "arrow-body-style": "off", diff --git a/package-lock.json b/package-lock.json index 473d0d119..b43e5f3c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "eslint-plugin-no-null": "^1.0.2", "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-hooks-static-deps": "^1.0.7", "eslint-plugin-teactn": "git+https://github.com/korenskoy/eslint-plugin-teactn#c2c39dd005d58c07c24c4361de804dce1c6261b5", "git-revision-webpack-plugin": "^5.0.0", "gitlog": "^4.0.4", @@ -7413,6 +7414,12 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" } }, + "node_modules/eslint-plugin-react-hooks-static-deps": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks-static-deps/-/eslint-plugin-react-hooks-static-deps-1.0.7.tgz", + "integrity": "sha512-K34LqdZaeqt9y9jsOmvkOUJT5ViTMYsHYm/7eV0WBGztOU36xxDTBZJS3hfJBW8tzzZcxSgsMvZIORzOkyojKQ==", + "dev": true + }, "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", diff --git a/package.json b/package.json index 8324821d4..b61764852 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "eslint-plugin-no-null": "^1.0.2", "eslint-plugin-react": "^7.31.11", "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-hooks-static-deps": "^1.0.7", "eslint-plugin-teactn": "git+https://github.com/korenskoy/eslint-plugin-teactn#c2c39dd005d58c07c24c4361de804dce1c6261b5", "git-revision-webpack-plugin": "^5.0.0", "gitlog": "^4.0.4", diff --git a/src/components/calls/group/GroupCallParticipantMenu.tsx b/src/components/calls/group/GroupCallParticipantMenu.tsx index 15d1d5c18..28666d751 100644 --- a/src/components/calls/group/GroupCallParticipantMenu.tsx +++ b/src/components/calls/group/GroupCallParticipantMenu.tsx @@ -80,7 +80,7 @@ const GroupCallParticipantMenu: FC = ({ ? VOLUME_ZERO : ((participant?.volume || GROUP_CALL_DEFAULT_VOLUME) / GROUP_CALL_VOLUME_MULTIPLIER)); // We only want to initialize local volume when switching participants and ignore following updates from server - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [id]); const runThrottled = useRunThrottled(VOLUME_CHANGE_THROTTLE); diff --git a/src/components/left/main/StatusButton.tsx b/src/components/left/main/StatusButton.tsx index 302ea9068..e32cef6e5 100644 --- a/src/components/left/main/StatusButton.tsx +++ b/src/components/left/main/StatusButton.tsx @@ -43,6 +43,7 @@ const StatusButton: FC = ({ emojiStatus }) => { showEffect(); unmarkShouldShowEffect(); } + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [emojiStatus, shouldShowEffect, showEffect, unmarkShouldShowEffect] as const); const handleEmojiStatusSet = useCallback((sticker: ApiSticker) => { diff --git a/src/components/left/search/AudioResults.tsx b/src/components/left/search/AudioResults.tsx index 618b0d584..f541c8d6e 100644 --- a/src/components/left/search/AudioResults.tsx +++ b/src/components/left/search/AudioResults.tsx @@ -54,7 +54,7 @@ const AudioResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [currentType, lastSyncTime, searchMessagesGlobal, searchQuery]); const foundMessages = useMemo(() => { diff --git a/src/components/left/search/ChatMessageResults.tsx b/src/components/left/search/ChatMessageResults.tsx index cfe7a1b33..fdaff8433 100644 --- a/src/components/left/search/ChatMessageResults.tsx +++ b/src/components/left/search/ChatMessageResults.tsx @@ -64,7 +64,7 @@ const ChatMessageResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [lastSyncTime, searchMessagesGlobal, searchQuery]); const handleTopicClick = useCallback( diff --git a/src/components/left/search/ChatResults.tsx b/src/components/left/search/ChatResults.tsx index 79d43ae7d..42734ac11 100644 --- a/src/components/left/search/ChatResults.tsx +++ b/src/components/left/search/ChatResults.tsx @@ -84,7 +84,7 @@ const ChatResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [lastSyncTime, searchMessagesGlobal, searchQuery]); const handleChatClick = useCallback( diff --git a/src/components/left/search/FileResults.tsx b/src/components/left/search/FileResults.tsx index 806ce3abc..bd54926ac 100644 --- a/src/components/left/search/FileResults.tsx +++ b/src/components/left/search/FileResults.tsx @@ -66,7 +66,7 @@ const FileResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [lastSyncTime, searchMessagesGlobal, searchQuery]); const foundMessages = useMemo(() => { diff --git a/src/components/left/search/LinkResults.tsx b/src/components/left/search/LinkResults.tsx index 8f9a8c953..a0143761d 100644 --- a/src/components/left/search/LinkResults.tsx +++ b/src/components/left/search/LinkResults.tsx @@ -64,7 +64,7 @@ const LinkResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [lastSyncTime, searchMessagesGlobal, searchQuery]); const foundMessages = useMemo(() => { diff --git a/src/components/left/search/MediaResults.tsx b/src/components/left/search/MediaResults.tsx index 453ee5c86..7539f823b 100644 --- a/src/components/left/search/MediaResults.tsx +++ b/src/components/left/search/MediaResults.tsx @@ -62,7 +62,7 @@ const MediaResults: FC = ({ }); }); } - // eslint-disable-next-line react-hooks/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `searchQuery` is required to prevent infinite message loading }, [lastSyncTime, searchMessagesGlobal, searchQuery]); const foundMessages = useMemo(() => { diff --git a/src/components/main/ConfettiContainer.tsx b/src/components/main/ConfettiContainer.tsx index 8a576877c..6beb54f26 100644 --- a/src/components/main/ConfettiContainer.tsx +++ b/src/components/main/ConfettiContainer.tsx @@ -181,7 +181,7 @@ const ConfettiContainer: FC = ({ confetti }) => { return () => { clearTimeout(hideTimeout); }; - // eslint-disable-next-line react-hooks/exhaustive-deps -- Old timeout should be cleared only if new confetti is generated + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- Old timeout should be cleared only if new confetti is generated }, [lastConfettiTime, forceUpdate, updateCanvas]); if (!lastConfettiTime || Date.now() - lastConfettiTime > CONFETTI_FADEOUT_TIMEOUT) { diff --git a/src/components/middle/MessageList.tsx b/src/components/middle/MessageList.tsx index cf9d3f1f5..73e41d73e 100644 --- a/src/components/middle/MessageList.tsx +++ b/src/components/middle/MessageList.tsx @@ -268,7 +268,7 @@ const MessageList: FC = ({ } return debounce(() => loadViewportMessages({ direction: LoadMoreDirection.Around }), 1000, true, false); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [loadViewportMessages, messageIds]); const { isScrolled, updateStickyDates } = useStickyDates(); @@ -491,7 +491,7 @@ const MessageList: FC = ({ console.timeEnd('scrollTop'); } // This should match deps for `useSyncEffect` above - // eslint-disable-next-line react-hooks/exhaustive-deps -- `as const` not yet supported by linter + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `as const` not yet supported by linter }, [messageIds, isViewportNewest, containerHeight, hasTools] as const); useEffectWithPrevDeps(([prevIsSelectModeActive]) => { diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index 0ce28266f..5b7502c71 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -582,9 +582,9 @@ const Composer: FC = ({ const stopRecordingVoiceRef = useStateRef(stopRecordingVoice); useEffect(() => { return () => { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps stopRecordingVoiceRef.current(); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps resetComposerRef.current(); }; }, [chatId, threadId, resetComposerRef, stopRecordingVoiceRef]); diff --git a/src/components/middle/composer/hooks/useDraft.ts b/src/components/middle/composer/hooks/useDraft.ts index c699499e9..8d3db5ba2 100644 --- a/src/components/middle/composer/hooks/useDraft.ts +++ b/src/components/middle/composer/hooks/useDraft.ts @@ -98,7 +98,7 @@ const useDraft = ( } }); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [ chatId, threadId, draft, setHtml, editedMessage, loadCustomEmojis, ] as const); @@ -106,9 +106,9 @@ const useDraft = ( // Save draft on chat change useEffect(() => { return () => { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps if (!isEditing) { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps updateDraftRef.current({ chatId, threadId }); } diff --git a/src/components/middle/composer/hooks/useEditing.ts b/src/components/middle/composer/hooks/useEditing.ts index 13f78c93e..e86e2c3ee 100644 --- a/src/components/middle/composer/hooks/useEditing.ts +++ b/src/components/middle/composer/hooks/useEditing.ts @@ -58,7 +58,7 @@ const useEditing = ( focusEditableElement(messageInput, true); } }); - // eslint-disable-next-line react-hooks/exhaustive-deps -- `as const` not yet supported by linter + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps -- `as const` not yet supported by linter }, [editedMessage, replyingToId, setHtml] as const); useEffect(() => { diff --git a/src/components/middle/composer/hooks/useInlineBotTooltip.ts b/src/components/middle/composer/hooks/useInlineBotTooltip.ts index b28d91abe..3126b98b9 100644 --- a/src/components/middle/composer/hooks/useInlineBotTooltip.ts +++ b/src/components/middle/composer/hooks/useInlineBotTooltip.ts @@ -45,7 +45,7 @@ export default function useInlineBotTooltip( if (prevUsername) { resetInlineBot({ username: prevUsername }); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [username, resetInlineBot] as const); useEffect(() => { diff --git a/src/components/middle/hooks/useScrollHooks.ts b/src/components/middle/hooks/useScrollHooks.ts index 0115d848b..a4db975e9 100644 --- a/src/components/middle/hooks/useScrollHooks.ts +++ b/src/components/middle/hooks/useScrollHooks.ts @@ -34,7 +34,7 @@ export default function useScrollHooks( debounce(() => loadViewportMessages({ direction: LoadMoreDirection.Backwards }), 1000, true, false), debounce(() => loadViewportMessages({ direction: LoadMoreDirection.Forwards }), 1000, true, false), ] : []), - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps [loadViewportMessages, messageIds], ); diff --git a/src/components/right/RightColumn.tsx b/src/components/right/RightColumn.tsx index 29ed8fd34..83b89a181 100644 --- a/src/components/right/RightColumn.tsx +++ b/src/components/right/RightColumn.tsx @@ -235,7 +235,7 @@ const RightColumn: FC = ({ if (isOpen && isOverlaying) { close(); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [isOverlaying]); // We need to clear profile state and management screen state, when changing chats diff --git a/src/components/right/hooks/useAsyncRendering.ts b/src/components/right/hooks/useAsyncRendering.ts index c62c1c132..c8c9e41bb 100644 --- a/src/components/right/hooks/useAsyncRendering.ts +++ b/src/components/right/hooks/useAsyncRendering.ts @@ -20,7 +20,7 @@ export default function useAsyncRendering(dependencies: T, dela clearTimeout(timeoutRef.current); timeoutRef.current = undefined; } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies); useEffect(() => { @@ -38,7 +38,7 @@ export default function useAsyncRendering(dependencies: T, dela } else { exec(); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies); return shouldRenderRef.current; diff --git a/src/components/ui/InfiniteScroll.tsx b/src/components/ui/InfiniteScroll.tsx index 341b4bc83..592445f03 100644 --- a/src/components/ui/InfiniteScroll.tsx +++ b/src/components/ui/InfiniteScroll.tsx @@ -86,7 +86,7 @@ const InfiniteScroll: FC = ({ onLoadMore({ direction: LoadMoreDirection.Forwards }); }, 1000, true, false), ]; - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [onLoadMore, items]); // Initial preload diff --git a/src/hooks/useAsync.ts b/src/hooks/useAsync.ts index 6088a05e9..fde727743 100644 --- a/src/hooks/useAsync.ts +++ b/src/hooks/useAsync.ts @@ -19,7 +19,7 @@ const useAsync = (fn: () => Promise, deps: any[], defaultValue?: T) => { return () => { wasCancelled = true; }; - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, deps); return { isLoading, error, result }; }; diff --git a/src/hooks/useAsyncResolvers.ts b/src/hooks/useAsyncResolvers.ts index 42f76c944..d7c9d568b 100644 --- a/src/hooks/useAsyncResolvers.ts +++ b/src/hooks/useAsyncResolvers.ts @@ -4,13 +4,13 @@ import useDebouncedCallback from './useDebouncedCallback'; export function useThrottledResolver(resolver: () => T, deps: any[], ms: number, noFirst = false) { return useThrottledCallback((setValue: (newValue: T) => void) => { setValue(resolver()); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, deps, ms, noFirst); } export function useDebouncedResolver(resolver: () => T, deps: any[], ms: number, noFirst = false, noLast = false) { return useDebouncedCallback((setValue: (newValue: T) => void) => { setValue(resolver()); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, deps, ms, noFirst, noLast); } diff --git a/src/hooks/useAudioPlayer.ts b/src/hooks/useAudioPlayer.ts index 6c439118f..483fdfcc3 100644 --- a/src/hooks/useAudioPlayer.ts +++ b/src/hooks/useAudioPlayer.ts @@ -106,7 +106,7 @@ const useAudioPlayer = ( if (!isPlaying && !proxy.paused) { setIsPlaying(true); // `isPlayingSync` is only needed to help `setIsPlaying` because it is asynchronous - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps isPlayingSync = true; } diff --git a/src/hooks/useBlurSync.ts b/src/hooks/useBlurSync.ts index 856c0418d..3e0baa5a4 100644 --- a/src/hooks/useBlurSync.ts +++ b/src/hooks/useBlurSync.ts @@ -14,7 +14,7 @@ export default function useBlurSync(dataUri: string | false | undefined) { let isChanged = false; useSyncEffect(() => { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps isChanged = true; blurredRef.current = undefined; diff --git a/src/hooks/useDebouncedCallback.ts b/src/hooks/useDebouncedCallback.ts index ac9f94623..d182e3c97 100644 --- a/src/hooks/useDebouncedCallback.ts +++ b/src/hooks/useDebouncedCallback.ts @@ -9,7 +9,7 @@ export default function useDebouncedCallback( noFirst = false, noLast = false, ) { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps const fnMemo = useCallback(fn, deps); return useMemo(() => { diff --git a/src/hooks/useDebouncedMemo.ts b/src/hooks/useDebouncedMemo.ts index 0d256b760..65e7d3209 100644 --- a/src/hooks/useDebouncedMemo.ts +++ b/src/hooks/useDebouncedMemo.ts @@ -21,7 +21,7 @@ export default function useDebouncedMemo( runDebounced(() => { setValue(resolverFn()); }); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [...dependencies, isFrozen]); return value; diff --git a/src/hooks/useDerivedSignal.ts b/src/hooks/useDerivedSignal.ts index c528ccc14..c00498485 100644 --- a/src/hooks/useDerivedSignal.ts +++ b/src/hooks/useDerivedSignal.ts @@ -31,10 +31,10 @@ function useDerivedSignal(resolverOrDependency: Resolver | T, dependencies } } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps useSyncEffect(runCurrentResolver, dependencies); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps useSignalEffect(runCurrentResolver, dependencies); return getValue as Signal; diff --git a/src/hooks/useDerivedState.ts b/src/hooks/useDerivedState.ts index 3b1480284..cd5f6ed66 100644 --- a/src/hooks/useDerivedState.ts +++ b/src/hooks/useDerivedState.ts @@ -48,10 +48,10 @@ function useDerivedState(resolverOrSignal: Resolver | T, dependencies?: re useSyncEffect(() => { runCurrentResolver(true); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps useSignalEffect(runCurrentResolver, dependencies); return valueRef.current as T; diff --git a/src/hooks/useEffectOnce.ts b/src/hooks/useEffectOnce.ts index 503300a14..20bdc20e4 100644 --- a/src/hooks/useEffectOnce.ts +++ b/src/hooks/useEffectOnce.ts @@ -1,7 +1,7 @@ import { useEffect } from '../lib/teact/teact'; function useEffectOnce(effect: React.EffectCallback) { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps useEffect(effect, []); } diff --git a/src/hooks/useEffectWithPrevDeps.ts b/src/hooks/useEffectWithPrevDeps.ts index 43ca51cc8..b6a709c1c 100644 --- a/src/hooks/useEffectWithPrevDeps.ts +++ b/src/hooks/useEffectWithPrevDeps.ts @@ -7,7 +7,7 @@ const useEffectWithPrevDeps = ( const prevDeps = usePrevious(dependencies); return useEffect(() => { return cb(prevDeps || []); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies, debugKey); }; diff --git a/src/hooks/useIntersectionObserver.ts b/src/hooks/useIntersectionObserver.ts index b37c9ac40..89cd8832f 100644 --- a/src/hooks/useIntersectionObserver.ts +++ b/src/hooks/useIntersectionObserver.ts @@ -147,7 +147,7 @@ export function useIntersectionObserver({ controller.observer.unobserve(target); }; // Arguments should never change - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, [isDisabled]); return { observe, freeze, unfreeze }; diff --git a/src/hooks/useLayoutEffectWithPrevDeps.ts b/src/hooks/useLayoutEffectWithPrevDeps.ts index dd1027e54..c31affd74 100644 --- a/src/hooks/useLayoutEffectWithPrevDeps.ts +++ b/src/hooks/useLayoutEffectWithPrevDeps.ts @@ -7,7 +7,7 @@ const useLayoutEffectWithPrevDeps = ( const prevDeps = usePrevious(dependencies); return useLayoutEffect(() => { return cb(prevDeps || []); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies, debugKey); }; diff --git a/src/hooks/useReducer.ts b/src/hooks/useReducer.ts index 9660c3b64..e0b7e1905 100644 --- a/src/hooks/useReducer.ts +++ b/src/hooks/useReducer.ts @@ -17,7 +17,7 @@ export default function useReducer( const dispatch = useCallback((action: ReducerAction) => { state.current = reducerRef.current(state.current, action); forceUpdate(); - }, [forceUpdate]); + }, []); return [ state.current, diff --git a/src/hooks/useRunDebounced.ts b/src/hooks/useRunDebounced.ts index 7cdcfb7d4..442a00219 100644 --- a/src/hooks/useRunDebounced.ts +++ b/src/hooks/useRunDebounced.ts @@ -3,6 +3,6 @@ import useDebouncedCallback from './useDebouncedCallback'; export default function useRunDebounced(ms: number, noFirst?: boolean, noLast?: boolean, deps: any = []) { return useDebouncedCallback((cb: NoneToVoidFunction) => { cb(); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, deps, ms, noFirst, noLast); } diff --git a/src/hooks/useRunThrottled.ts b/src/hooks/useRunThrottled.ts index 9a1602e44..c86c8a4e1 100644 --- a/src/hooks/useRunThrottled.ts +++ b/src/hooks/useRunThrottled.ts @@ -3,6 +3,6 @@ import useThrottledCallback from './useThrottledCallback'; export default function useRunThrottled(ms: number, noFirst?: boolean, deps: any = []) { return useThrottledCallback((cb: NoneToVoidFunction) => { cb(); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, deps, ms, noFirst); } diff --git a/src/hooks/useThrottledCallback.ts b/src/hooks/useThrottledCallback.ts index a97573b05..54fad98ab 100644 --- a/src/hooks/useThrottledCallback.ts +++ b/src/hooks/useThrottledCallback.ts @@ -9,7 +9,7 @@ export default function useThrottledCallback( msOrRaf: number | typeof fastRaf, noFirst = false, ) { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps const fnMemo = useCallback(fn, deps); return useMemo(() => { diff --git a/src/hooks/useVideoCleanup.ts b/src/hooks/useVideoCleanup.ts index 02f1962d7..4e587a44e 100644 --- a/src/hooks/useVideoCleanup.ts +++ b/src/hooks/useVideoCleanup.ts @@ -16,6 +16,6 @@ export default function useVideoCleanup(videoRef: RefObject, d }); } }; - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps }, dependencies); } diff --git a/src/lib/teact/teact.ts b/src/lib/teact/teact.ts index cd29fc2e7..2b9d5c08c 100644 --- a/src/lib/teact/teact.ts +++ b/src/lib/teact/teact.ts @@ -759,7 +759,7 @@ export function useMemo(resolver: () => T, dependencies: any[], d } export function useCallback(newCallback: F, dependencies: any[], debugKey?: string): F { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps return useMemo(() => newCallback, dependencies, debugKey); } @@ -782,7 +782,7 @@ export function useRef(initial?: T | null) { export function memo(Component: T, debugKey?: string) { return function TeactMemoWrapper(props: Props) { - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps return useMemo(() => createElement(Component, props), Object.values(props), debugKey); } as T; }