From 4c1373080b528e9c80e45409cc4059be6db9d4b0 Mon Sep 17 00:00:00 2001 From: "junyoung.lim" Date: Thu, 9 Jan 2025 17:53:55 +0900 Subject: [PATCH 1/2] Update and propagate groupChannel state properly --- .../GroupChannel/context/GroupChannelProvider.tsx | 7 +------ .../GroupChannel/context/hooks/useGroupChannel.ts | 2 +- .../context/GroupChannelListProvider.tsx | 5 ++++- .../GroupChannelList/context/useGroupChannelList.ts | 12 ++++++++++-- src/utils/storeManager.ts | 6 +++--- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/modules/GroupChannel/context/GroupChannelProvider.tsx b/src/modules/GroupChannel/context/GroupChannelProvider.tsx index 15c616a0e..bd76b0d8a 100644 --- a/src/modules/GroupChannel/context/GroupChannelProvider.tsx +++ b/src/modules/GroupChannel/context/GroupChannelProvider.tsx @@ -163,12 +163,7 @@ const GroupChannelManager :React.FC { - // Note: this shouldn't happen ideally, but it happens on re-rendering GroupChannelManager - // even though the next channel and the current channel are the same. - // So added this condition to check if they are the same to prevent unnecessary calling setCurrentChannel action - if (!state.currentChannel?.isEqual(channel)) { - actions.setCurrentChannel(channel); - } + actions.setCurrentChannel(channel); }, logger: logger as any, }); diff --git a/src/modules/GroupChannel/context/hooks/useGroupChannel.ts b/src/modules/GroupChannel/context/hooks/useGroupChannel.ts index 0a9b67f49..4cca12811 100644 --- a/src/modules/GroupChannel/context/hooks/useGroupChannel.ts +++ b/src/modules/GroupChannel/context/hooks/useGroupChannel.ts @@ -165,7 +165,7 @@ export const useGroupChannel = () => { nicknamesMap: new Map( channel.members.map(({ userId, nickname }) => [userId, nickname]), ), - })); + }), true); }, []); const handleChannelError = useCallback((error: SendbirdError) => { diff --git a/src/modules/GroupChannelList/context/GroupChannelListProvider.tsx b/src/modules/GroupChannelList/context/GroupChannelListProvider.tsx index 405c14b2d..cd1d41e14 100644 --- a/src/modules/GroupChannelList/context/GroupChannelListProvider.tsx +++ b/src/modules/GroupChannelList/context/GroupChannelListProvider.tsx @@ -108,7 +108,7 @@ export const GroupChannelListManager: React.FC = }: GroupChannelListProviderProps) => { const { state: sendbirdState } = useSendbird(); const { config, stores } = sendbirdState; - const { state } = useGroupChannelList(); + const { state, actions } = useGroupChannelList(); const { updateState } = useGroupChannelListStore(); const { sdkStore } = stores; @@ -126,6 +126,9 @@ export const GroupChannelListManager: React.FC = if (url === selectedChannelUrl) onChannelSelect(null); }); }, + onChannelsUpdated: () => { + actions.setGroupChannels(groupChannels); + }, }); const { refreshing, initialized, groupChannels, refresh, loadMore } = channelListDataSource; diff --git a/src/modules/GroupChannelList/context/useGroupChannelList.ts b/src/modules/GroupChannelList/context/useGroupChannelList.ts index bbf636aee..79caf6594 100644 --- a/src/modules/GroupChannelList/context/useGroupChannelList.ts +++ b/src/modules/GroupChannelList/context/useGroupChannelList.ts @@ -1,14 +1,22 @@ import { useSyncExternalStore } from 'use-sync-external-store/shim'; -import { useMemo, useContext } from 'react'; +import { useMemo, useContext, useCallback } from 'react'; import { GroupChannelListState, GroupChannelListContext } from './GroupChannelListProvider'; export const useGroupChannelList = () => { const store = useContext(GroupChannelListContext); if (!store) throw new Error('useGroupChannelList must be used within a GroupChannelListProvider'); + const setGroupChannels = useCallback((channels) => { + store.setState(state => ({ + ...state, + groupChannels: channels, + }), true); + }, []); + const state: GroupChannelListState = useSyncExternalStore(store.subscribe, store.getState); const actions = useMemo(() => ({ - }), [store]); + setGroupChannels, + }), [setGroupChannels]); return { state, actions }; }; diff --git a/src/utils/storeManager.ts b/src/utils/storeManager.ts index b825faa5f..18fcc4799 100644 --- a/src/utils/storeManager.ts +++ b/src/utils/storeManager.ts @@ -3,7 +3,7 @@ import isEqual from 'lodash/isEqual'; // Referrence: https://github.com/pmndrs/zustand export type Store = { getState: () => T; - setState: (partial: Partial | ((state: T) => Partial)) => void; + setState: (partial: Partial | ((state: T) => Partial), force?: boolean) => void; subscribe: (listener: () => void) => () => void; }; @@ -30,7 +30,7 @@ export function createStore(initialState: T): Store { const listeners = new Set<() => void>(); let isUpdating = false; - const setState = (partial: Partial | ((state: T) => Partial)) => { + const setState = (partial: Partial | ((state: T) => Partial), force?: boolean) => { // Prevent nested updates if (isUpdating) return; @@ -39,7 +39,7 @@ export function createStore(initialState: T): Store { const nextState = typeof partial === 'function' ? partial(state) : partial; const hasChanged = hasStateChanged(state, nextState); - if (hasChanged) { + if (force || hasChanged) { state = { ...state, ...nextState }; listeners.forEach((listener) => listener()); } From ebe18bdec673f5cf73fb1d16118950edd6e98c48 Mon Sep 17 00:00:00 2001 From: "junyoung.lim" Date: Fri, 10 Jan 2025 17:14:09 +0900 Subject: [PATCH 2/2] Fix import order --- src/modules/GroupChannel/context/hooks/useGroupChannel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/GroupChannel/context/hooks/useGroupChannel.ts b/src/modules/GroupChannel/context/hooks/useGroupChannel.ts index 4cca12811..b4d255d81 100644 --- a/src/modules/GroupChannel/context/hooks/useGroupChannel.ts +++ b/src/modules/GroupChannel/context/hooks/useGroupChannel.ts @@ -1,4 +1,4 @@ -import { useContext, useMemo, useCallback } from 'react'; +import { useContext, useCallback, useMemo } from 'react'; import type { GroupChannel } from '@sendbird/chat/groupChannel'; import type { SendbirdError } from '@sendbird/chat'; import { useSyncExternalStore } from 'use-sync-external-store/shim';