Skip to content

Commit 469b052

Browse files
committed
fix(frontend): 修复文章列表页翻页速度过快时导致的内容错乱问题
修复文章列表页翻页速度过快时导致的内容错乱问题
1 parent 981f7d8 commit 469b052

3 files changed

Lines changed: 40 additions & 10 deletions

File tree

frontend/src/Api.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import apiClient from './utils/axios';
22

33
// 获取文章列表
4-
export const fetchArticles = async (page = 1, size = 10, category = null) => {
4+
export const fetchArticles = async (page = 1, size = 10, category = null, signal = null) => {
55
try {
66
const params = { page, size };
77
if (category) {
88
params.category = category;
99
}
1010

11-
const response = await apiClient.get('/articles', { params });
11+
const config = { params };
12+
if (signal) {
13+
config.signal = signal;
14+
}
15+
16+
const response = await apiClient.get('/articles', config);
1217
return response;
1318
} catch (error) {
1419
console.error('获取文章列表失败:', error);

frontend/src/components/ArticleList.jsx

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default function ArticleList() {
2424

2525
const gridRef = useRef(null);
2626
const [holdHeight, setHoldHeight] = useState(null);
27+
const abortControllerRef = useRef(null);
2728

2829
useEffect(() => {
2930
const checkMobile = () => setForceMobile(window.innerWidth < 768);
@@ -40,13 +41,24 @@ export default function ArticleList() {
4041

4142
useEffect(() => {
4243
loadArticlesFromUrl();
44+
return () => {
45+
if (abortControllerRef.current) {
46+
abortControllerRef.current.abort();
47+
}
48+
};
4349
}, [location.search, location.pathname, pageParam, tagName]);
4450

4551
useEffect(() => {
4652
localStorage.setItem('showImages', JSON.stringify(showImages));
4753
}, [showImages]);
4854

4955
const loadArticlesFromUrl = async () => {
56+
if (abortControllerRef.current) {
57+
abortControllerRef.current.abort();
58+
}
59+
const abortController = new AbortController();
60+
abortControllerRef.current = abortController;
61+
5062
try {
5163
if (gridRef.current) {
5264
setHoldHeight(gridRef.current.offsetHeight);
@@ -55,21 +67,30 @@ export default function ArticleList() {
5567
let result;
5668

5769
if (categoryName) {
58-
result = await apiClient.get(`/categories/articles?category=${encodeURIComponent(categoryName)}&page=${pageParam}&size=6`);
70+
result = await apiClient.get(`/categories/articles?category=${encodeURIComponent(categoryName)}&page=${pageParam}&size=6`, { signal: abortController.signal });
5971
} else if (tagName) {
60-
result = await apiClient.get(`/tags/${tagName}/articles?page=${pageParam}&size=6`);
72+
result = await apiClient.get(`/tags/${tagName}/articles?page=${pageParam}&size=6`, { signal: abortController.signal });
6173
} else {
62-
result = await fetchArticles(pageParam, 6);
74+
result = await fetchArticles(pageParam, 6, null, abortController.signal);
6375
}
6476

65-
setArticles(Array.isArray(result.data) ? result.data : []);
66-
setTotalPages(result.total_pages || 1);
77+
if (!abortController.signal.aborted) {
78+
setArticles(Array.isArray(result.data) ? result.data : []);
79+
setTotalPages(result.total_pages || 1);
80+
}
6781
} catch (error) {
82+
if (error.name === 'AbortError' || error.code === 'ERR_CANCELED') {
83+
return;
84+
}
6885
console.error('加载文章失败:', error);
69-
setArticles([]);
70-
setTotalPages(1);
86+
if (!abortController.signal.aborted) {
87+
setArticles([]);
88+
setTotalPages(1);
89+
}
7190
} finally {
72-
setLoading(false);
91+
if (!abortController.signal.aborted) {
92+
setLoading(false);
93+
}
7394
}
7495
};
7596

frontend/src/utils/axios.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ apiClient.interceptors.response.use(
2323
return response.data;
2424
},
2525
(error) => {
26+
if (error.code === 'ERR_CANCELED' || error.name === 'CanceledError') {
27+
return Promise.reject(error);
28+
}
29+
2630
const silent = error.config?.silent === true;
2731
if (error.response?.status === 429) {
2832
const message = error.response.data?.message || '请求过于频繁,请稍后再试';

0 commit comments

Comments
 (0)