Просмотр исходного кода

fix(admin): stop infinite render loop on G2G data transfer page

updateSelectedCollections and updateOptionsMap were plain inline
functions, so the parent emitted new references on every render. The
child's setInitialOptionsMap useCallback (deps: [allCollectionNames,
updateOptionsMap]) and its driving useEffect therefore re-ran on every
render, triggering setOptionsMap → re-render → loop. The browser hit
"Maximum update depth exceeded" and the page froze.

Wrap both update wrappers in useCallback with empty deps so their
references are stable across renders.

Fixes #11127

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Shun Miyazawa 1 неделя назад
Родитель
Сommit
aad7937925
1 измененных файлов с 8 добавлено и 5 удалено
  1. 8 5
      apps/app/src/client/components/Admin/G2GDataTransfer.tsx

+ 8 - 5
apps/app/src/client/components/Admin/G2GDataTransfer.tsx

@@ -54,13 +54,16 @@ const G2GDataTransfer = (): JSX.Element => {
   // const [gcsBucket, setGcsBucket] = useState('');
   // const [gcsBucket, setGcsBucket] = useState('');
   // const [gcsUploadNamespace, setGcsUploadNamespace] = useState('');
   // const [gcsUploadNamespace, setGcsUploadNamespace] = useState('');
 
 
-  const updateSelectedCollections = (newSelectedCollections: Set<string>) => {
-    setSelectedCollections(newSelectedCollections);
-  };
+  const updateSelectedCollections = useCallback(
+    (newSelectedCollections: Set<string>) => {
+      setSelectedCollections(newSelectedCollections);
+    },
+    [],
+  );
 
 
-  const updateOptionsMap = (newOptionsMap: any) => {
+  const updateOptionsMap = useCallback((newOptionsMap: any) => {
     setOptionsMap(newOptionsMap);
     setOptionsMap(newOptionsMap);
-  };
+  }, []);
 
 
   const onChangeTransferKeyHandler = useCallback((e) => {
   const onChangeTransferKeyHandler = useCallback((e) => {
     setStartTransferKey(e.target.value);
     setStartTransferKey(e.target.value);