diff --git a/src/components/Channel/Channel.js b/src/components/Channel/Channel.js index b8ee79e84..dcd50109d 100644 --- a/src/components/Channel/Channel.js +++ b/src/components/Channel/Channel.js @@ -23,6 +23,7 @@ import { } from '../Loading'; import useMentionsHandlers from './hooks/useMentionsHandlers'; import useEditMessageHandler from './hooks/useEditMessageHandler'; +import useIsMounted from './hooks/useIsMounted'; import { channelReducer, initialState } from './channelState'; /** @type {React.FC}>} */ @@ -138,6 +139,7 @@ const ChannelInner = ({ const lastRead = useRef(new Date()); const chatContext = useContext(ChatContext); const online = useRef(true); + const isMounted = useIsMounted(); const { t } = useContext(TranslationContext); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -270,6 +272,7 @@ const ChannelInner = ({ * @param {import('stream-chat').ChannelState['messages']} messages */ (hasMore, messages) => { + if (!isMounted.current) return; dispatch({ type: 'loadMoreFinished', hasMore, messages }); }, 2000, diff --git a/src/components/Channel/__tests__/useIsMounted.test.js b/src/components/Channel/__tests__/useIsMounted.test.js new file mode 100644 index 000000000..2a901048f --- /dev/null +++ b/src/components/Channel/__tests__/useIsMounted.test.js @@ -0,0 +1,14 @@ +import { renderHook, act } from '@testing-library/react-hooks'; +import useIsMounted from '../hooks/useIsMounted'; + +describe('useIsMounted hook', () => { + it('should set the value to false after unmounting', () => { + const renderResult = renderHook(() => useIsMounted()); + const ref = renderResult.result.current; + expect(ref.current).toBe(true); + act(() => { + renderResult.unmount(); + }); + expect(ref.current).toBe(false); + }); +}); diff --git a/src/components/Channel/hooks/useIsMounted.js b/src/components/Channel/hooks/useIsMounted.js new file mode 100644 index 000000000..a0136300f --- /dev/null +++ b/src/components/Channel/hooks/useIsMounted.js @@ -0,0 +1,11 @@ +import { useRef, useEffect } from 'react'; + +export default () => { + const isMounted = useRef(true); + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + return isMounted; +};