mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
refactor: Enhance fetchIssues logic with mounted state checks
- Introduced a useRef hook to track component mount status, preventing state updates on unmounted components. - Updated fetchIssues function to conditionally set state only if the component is still mounted, improving reliability during asynchronous operations. - Ensured proper cleanup in useEffect to maintain accurate mounted state, enhancing overall component stability.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import { getElectronAPI, GitHubIssue } from '@/lib/electron';
|
import { getElectronAPI, GitHubIssue } from '@/lib/electron';
|
||||||
import { useAppStore } from '@/store/app-store';
|
import { useAppStore } from '@/store/app-store';
|
||||||
|
|
||||||
@@ -9,19 +9,25 @@ export function useGithubIssues() {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const isMountedRef = useRef(true);
|
||||||
|
|
||||||
const fetchIssues = useCallback(async () => {
|
const fetchIssues = useCallback(async () => {
|
||||||
if (!currentProject?.path) {
|
if (!currentProject?.path) {
|
||||||
|
if (isMountedRef.current) {
|
||||||
setError('No project selected');
|
setError('No project selected');
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (isMountedRef.current) {
|
||||||
setError(null);
|
setError(null);
|
||||||
|
}
|
||||||
const api = getElectronAPI();
|
const api = getElectronAPI();
|
||||||
if (api.github) {
|
if (api.github) {
|
||||||
const result = await api.github.listIssues(currentProject.path);
|
const result = await api.github.listIssues(currentProject.path);
|
||||||
|
if (isMountedRef.current) {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
setOpenIssues(result.openIssues || []);
|
setOpenIssues(result.openIssues || []);
|
||||||
setClosedIssues(result.closedIssues || []);
|
setClosedIssues(result.closedIssues || []);
|
||||||
@@ -29,21 +35,33 @@ export function useGithubIssues() {
|
|||||||
setError(result.error || 'Failed to fetch issues');
|
setError(result.error || 'Failed to fetch issues');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (isMountedRef.current) {
|
||||||
console.error('[GitHubIssuesView] Error fetching issues:', err);
|
console.error('[GitHubIssuesView] Error fetching issues:', err);
|
||||||
setError(err instanceof Error ? err.message : 'Failed to fetch issues');
|
setError(err instanceof Error ? err.message : 'Failed to fetch issues');
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
if (isMountedRef.current) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, [currentProject?.path]);
|
}, [currentProject?.path]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
isMountedRef.current = true;
|
||||||
fetchIssues();
|
fetchIssues();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
isMountedRef.current = false;
|
||||||
|
};
|
||||||
}, [fetchIssues]);
|
}, [fetchIssues]);
|
||||||
|
|
||||||
const refresh = useCallback(() => {
|
const refresh = useCallback(() => {
|
||||||
|
if (isMountedRef.current) {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
|
}
|
||||||
fetchIssues();
|
fetchIssues();
|
||||||
}, [fetchIssues]);
|
}, [fetchIssues]);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user