Skip to content

Commit 8a4263a

Browse files
Use useEffect instead of useDeepCompareEffect in GroupChannelListProvider (#1272)
Fixes - https://sendbird.atlassian.net/browse/CLNP-5966 - https://sendbird.atlassian.net/browse/CLNP-5967 - https://sendbird.atlassian.net/browse/CLNP-5969 - https://sendbird.atlassian.net/browse/CLNP-5971 - https://sendbird.atlassian.net/browse/CLNP-5973 ## When to use useDeepCompareEffect vs useEffect ### useDeepCompareEffect is useful when: 1. **Handling objects without guaranteed immutability** ```typescript const complexObject = { settings: { theme: { ... }, preferences: { ... } }, data: [ ... ] }; useDeepCompareEffect(() => { // When you want to detect actual value changes }, [complexObject]); ``` 2. **Working with data from external libraries or APIs** - When objects have new references but identical content 3. **Dealing with deeply nested objects where memoization is impractical** - When object structures are too complex for individual memoization ### useEffect is better when: 1. **Detecting changes in array items** ```typescript const items = [{id: 1, value: 'a'}, {id: 2, value: 'b'}]; // Better for detecting changes within array items useEffect(() => { // Detect changes in items array }, [items]); ``` 2. **Performance is critical** - Deep comparison is computationally expensive - Especially important for large arrays or frequently updating data ### Example of proper useDeepCompareEffect usage: ```typescript useDeepCompareEffect(() => { updateState({ ...configurations, ...scrollState, ...eventHandlers, }); }, [ configurations, scrollState, eventHandlers, ]); ``` This works well here because: - Dependencies are mostly objects - Updates are needed only when internal structure changes - Objects are already memoized, reducing deep comparison cost ### Key Takeaway: - Use useDeepCompareEffect when structural equality matters - Use useEffect for reference equality or primitive value changes - Consider the trade-off between performance and accuracy --------- Co-authored-by: junyoung.lim <[email protected]>
1 parent 8d1bfaa commit 8a4263a

File tree

3 files changed

+19
-8
lines changed

3 files changed

+19
-8
lines changed

src/hooks/useDeepCompareEffect.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,24 @@ function useDeepCompareMemoize<T>(value: T): T {
1313

1414
/**
1515
* Custom hook that works like useEffect but performs a deep comparison of dependencies
16-
* instead of reference equality. This is useful when dealing with complex objects or arrays
17-
* in dependencies that could trigger unnecessary re-renders.
16+
* instead of reference equality.
1817
*
19-
* Inspired by https://github.com/kentcdodds/use-deep-compare-effect
18+
* Best used when:
19+
* - Working with complex objects without guaranteed immutability
20+
* - Handling data from external sources where reference equality isn't maintained
21+
* - Dealing with deeply nested objects where individual memoization is impractical
2022
*
21-
* @param callback Effect callback that can either return nothing (void) or return a cleanup function (() => void).
23+
* Avoid using when:
24+
* - Detecting changes within array items is crucial
25+
* - Performance is critical (deep comparison is expensive)
26+
* - Working primarily with primitive values or simple objects
27+
*
28+
* @example
29+
* useDeepCompareEffect(() => {
30+
* // Effect logic
31+
* }, [complexObject, anotherObject]);
32+
*
33+
* @param callback Effect callback that can return a cleanup function
2234
* @param dependencies Array of dependencies to be deeply compared
2335
*/
2436
function useDeepCompareEffect(

src/modules/GroupChannelList/context/GroupChannelListProvider.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,16 @@ export const GroupChannelListManager: React.FC<GroupChannelListProviderProps> =
203203
refresh,
204204
loadMore,
205205
]);
206-
const memoizedGroupChannel = useMemo(() => groupChannels, [groupChannels]);
207206
useDeepCompareEffect(() => {
208207
updateState({
209-
groupChannels: memoizedGroupChannel,
210208
...eventHandlers,
211209
...configurations,
210+
groupChannels,
212211
});
213212
}, [
214213
configurations,
215214
eventHandlers,
216-
memoizedGroupChannel,
215+
groupChannels.map(groupChannel => groupChannel.serialize()),
217216
]);
218217

219218
return null;

src/modules/GroupChannelList/context/__tests__/GroupChannelListProvider.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jest.mock('@sendbird/uikit-tools', () => ({
3131
useGroupChannelList: jest.fn(() => ({
3232
refreshing: false,
3333
initialized: true,
34-
groupChannels: [{ url: 'test-groupchannel-url-1' }],
34+
groupChannels: [{ url: 'test-groupchannel-url-1', serialize: () => JSON.stringify(this) }],
3535
refresh: null,
3636
loadMore: null,
3737
})),

0 commit comments

Comments
 (0)