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

修复搜索/切Tab/翻页时旧请求晚到污染列表的竞态

新增 reqIdRef 作为请求代次标记:
- handleSearch / handleChangeSource / jumpToPage / useEffect[visible] 触发新搜索时自增
- getVideoList 进入时快照 myReqId,await 后若与最新 reqId 不一致直接丢弃响应
- handleSearch 补 setVideoList([]) + setTotal(0),搜索瞬间清空旧数据
刘立冬 4 дней назад
Родитель
Сommit
7f3c6dd104

+ 8 - 0
src/views/publishContent/weCom/components/videoSelectModal/index.tsx

@@ -144,6 +144,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 	const loadingRef = useRef(false);
 	const loadingRef = useRef(false);
 	const currentPageRef = useRef(1);
 	const currentPageRef = useRef(1);
 	const getVideoListRef = useRef<(pageNum: number, mode: LoadMode) => Promise<void>>();
 	const getVideoListRef = useRef<(pageNum: number, mode: LoadMode) => Promise<void>>();
+	const reqIdRef = useRef(0);
 	const MAX_SELECTION = 3;
 	const MAX_SELECTION = 3;
 
 
 	useEffect(() => { hasMoreRef.current = hasMore; }, [hasMore]);
 	useEffect(() => { hasMoreRef.current = hasMore; }, [hasMore]);
@@ -161,6 +162,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 		}
 		}
 		setCurrentPage(pageNum);
 		setCurrentPage(pageNum);
 
 
+		const myReqId = reqIdRef.current;
 		const type = planType === WeComPlanType.社群 ? VideoSearchPlanType.企微社群 : VideoSearchPlanType.企微自动回复;
 		const type = planType === WeComPlanType.社群 ? VideoSearchPlanType.企微社群 : VideoSearchPlanType.企微自动回复;
 		const requestParams = { category, title: searchTerm, sort, type, pageNum, pageSize: PAGE_SIZE, ...(source ? { source } : {}) };
 		const requestParams = { category, title: searchTerm, sort, type, pageNum, pageSize: PAGE_SIZE, ...(source ? { source } : {}) };
 
 
@@ -174,6 +176,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 				setLoading(false);
 				setLoading(false);
 			}
 			}
 		});
 		});
+		if (myReqId !== reqIdRef.current) return;
 		if (res && res.code === 0) {
 		if (res && res.code === 0) {
 			const mapped = (res.data.objs || []).map(video => ({ ...video, scene: 0 as 0 | 1 }));
 			const mapped = (res.data.objs || []).map(video => ({ ...video, scene: 0 as 0 | 1 }));
 			if (mode === 'append') {
 			if (mode === 'append') {
@@ -266,6 +269,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 	}, []);
 	}, []);
 
 
 	const jumpToPage = (page: number) => {
 	const jumpToPage = (page: number) => {
+		reqIdRef.current++;
 		setHasMore(true);
 		setHasMore(true);
 		setVideoList([]);
 		setVideoList([]);
 		setPageAnchors(new Map());
 		setPageAnchors(new Map());
@@ -276,7 +280,10 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 	};
 	};
 
 
 	const handleSearch = () => {
 	const handleSearch = () => {
+		reqIdRef.current++;
 		setHasMore(true);
 		setHasMore(true);
+		setVideoList([]);
+		setTotal(0);
 		setViewingPage(1);
 		setViewingPage(1);
 		setPageAnchors(new Map());
 		setPageAnchors(new Map());
 		passedPagesRef.current.clear();
 		passedPagesRef.current.clear();
@@ -284,6 +291,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ visible, onClose, o
 	};
 	};
 
 
 	const handleChangeSource = (value: string) => {
 	const handleChangeSource = (value: string) => {
+		reqIdRef.current++;
 		setSource(value);
 		setSource(value);
 		setHasMore(true);
 		setHasMore(true);
 		setVideoList([]);
 		setVideoList([]);

+ 9 - 0
src/views/publishContent/weGZH/components/videoSelectModal/index.tsx

@@ -139,6 +139,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 	const loadingRef = useRef(false);
 	const loadingRef = useRef(false);
 	const currentPageRef = useRef(1);
 	const currentPageRef = useRef(1);
 	const getVideoListRef = useRef<(pageNum: number, mode: LoadMode) => Promise<void>>();
 	const getVideoListRef = useRef<(pageNum: number, mode: LoadMode) => Promise<void>>();
+	const reqIdRef = useRef(0);
 	const MAX_SELECTION = 3;
 	const MAX_SELECTION = 3;
 
 
 	useEffect(() => { hasMoreRef.current = hasMore; }, [hasMore]);
 	useEffect(() => { hasMoreRef.current = hasMore; }, [hasMore]);
@@ -166,6 +167,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 		}
 		}
 		setCurrentPage(pageNum);
 		setCurrentPage(pageNum);
 
 
+		const myReqId = reqIdRef.current;
 		const requestParams = {
 		const requestParams = {
 			category,
 			category,
 			title: searchTerm,
 			title: searchTerm,
@@ -186,6 +188,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 				setLoading(false);
 				setLoading(false);
 			}
 			}
 		});
 		});
+		if (myReqId !== reqIdRef.current) return;
 		if (res && res.code === 0) {
 		if (res && res.code === 0) {
 			const items = res.data.objs || [];
 			const items = res.data.objs || [];
 			if (mode === 'append') {
 			if (mode === 'append') {
@@ -214,6 +217,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 
 
 	useEffect(() => {
 	useEffect(() => {
 		if (visible) {
 		if (visible) {
+			reqIdRef.current++;
 			setVideoList(selectedVideos);
 			setVideoList(selectedVideos);
 			setVideoListAll(selectedVideos);
 			setVideoListAll(selectedVideos);
 			setHasMore(true);
 			setHasMore(true);
@@ -289,6 +293,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 	}, []);
 	}, []);
 
 
 	const jumpToPage = (page: number) => {
 	const jumpToPage = (page: number) => {
+		reqIdRef.current++;
 		setHasMore(true);
 		setHasMore(true);
 		setVideoList([]);
 		setVideoList([]);
 		setPageAnchors(new Map());
 		setPageAnchors(new Map());
@@ -299,7 +304,10 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 	};
 	};
 
 
 	const handleSearch = () => {
 	const handleSearch = () => {
+		reqIdRef.current++;
 		setHasMore(true);
 		setHasMore(true);
+		setVideoList([]);
+		setTotal(0);
 		setViewingPage(1);
 		setViewingPage(1);
 		setPageAnchors(new Map());
 		setPageAnchors(new Map());
 		passedPagesRef.current.clear();
 		passedPagesRef.current.clear();
@@ -307,6 +315,7 @@ const VideoSelectModal: React.FC<VideoSelectModalProps> = ({ planType, visible,
 	};
 	};
 
 
 	const handleChangeSource = (value: string) => {
 	const handleChangeSource = (value: string) => {
+		reqIdRef.current++;
 		setSource(value);
 		setSource(value);
 		setHasMore(true);
 		setHasMore(true);
 		setVideoList([]);
 		setVideoList([]);