diff --git a/lib/shared/search-utils.js b/lib/shared/search-utils.js --- a/lib/shared/search-utils.js +++ b/lib/shared/search-utils.js @@ -229,18 +229,20 @@ onResultsReceived: ( messages: $ReadOnlyArray, endReached: boolean, + queryID: number, threadID: string, ) => mixed, + queryID: number, cursor?: string, ) => void { const callSearchMessages = useServerCall(searchMessages); const dispatchActionPromise = useDispatchActionPromise(); return React.useCallback( - (query, threadID, onResultsReceived, cursor) => { + (query, threadID, onResultsReceived, queryID, cursor) => { const searchMessagesPromise = (async () => { if (query === '') { - onResultsReceived([], true, threadID); + onResultsReceived([], true, queryID, threadID); return; } const { messages, endReached } = await callSearchMessages({ @@ -248,7 +250,7 @@ threadID, cursor, }); - onResultsReceived(messages, endReached, threadID); + onResultsReceived(messages, endReached, queryID, threadID); })(); dispatchActionPromise(searchMessagesActionTypes, searchMessagesPromise); diff --git a/native/search/message-search.react.js b/native/search/message-search.react.js --- a/native/search/message-search.react.js +++ b/native/search/message-search.react.js @@ -47,7 +47,14 @@ const [endReached, setEndReached] = React.useState(false); const appendSearchResults = React.useCallback( - (newMessages: $ReadOnlyArray, end: boolean) => { + ( + newMessages: $ReadOnlyArray, + end: boolean, + queryID: number, + ) => { + if (queryID !== queryIDRef.current) { + return; + } setSearchResults(oldMessages => [...oldMessages, ...newMessages]); setEndReached(end); }, @@ -56,16 +63,24 @@ const searchMessages = useSearchMessages(); + const queryIDRef = React.useRef(0); + React.useEffect(() => { setSearchResults([]); setLastID(undefined); setEndReached(false); }, [query, searchMessages]); - React.useEffect( - () => searchMessages(query, threadInfo.id, appendSearchResults, lastID), - [appendSearchResults, lastID, query, searchMessages, threadInfo.id], - ); + React.useEffect(() => { + queryIDRef.current += 1; + searchMessages( + query, + threadInfo.id, + appendSearchResults, + queryIDRef.current, + lastID, + ); + }, [appendSearchResults, lastID, query, searchMessages, threadInfo.id]); const userInfos = useSelector(state => state.userStore.userInfos); diff --git a/web/search/message-search-state-provider.react.js b/web/search/message-search-state-provider.react.js --- a/web/search/message-search-state-provider.react.js +++ b/web/search/message-search-state-provider.react.js @@ -114,13 +114,19 @@ const searchMessagesCall = useSearchMessages(); const loading = React.useRef(false); + const queryIDRef = React.useRef(0); const appendResults = React.useCallback( ( newMessages: $ReadOnlyArray, end: boolean, + queryID: number, threadID: string, ) => { + if (queryID !== queryIDRef.current) { + return; + } + appendResult(newMessages, threadID); if (end) { setEndReached(threadID); @@ -135,11 +141,13 @@ if (loading.current || endsReached.current.has(threadID)) { return; } + queryIDRef.current += 1; loading.current = true; searchMessagesCall( queries.current[threadID], threadID, appendResults, + queryIDRef.current, lastIDs.current[threadID], ); },