Skip to content

Commit eb9a3d8

Browse files
authored
fix: add memoization in ReactionList to update MessageOverlay in Real time (#1737)
1 parent f41e9fd commit eb9a3d8

File tree

3 files changed

+77
-83
lines changed

3 files changed

+77
-83
lines changed

examples/TypeScriptMessaging/App.tsx

Lines changed: 64 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,17 @@ const ChannelListScreen: React.FC<ChannelListScreenProps> = ({ navigation }) =>
8484
const memoizedFilters = useMemo(() => filters, []);
8585

8686
return (
87-
<Chat client={chatClient} i18nInstance={streami18n}>
88-
<View style={{ height: '100%' }}>
89-
<ChannelList<StreamChatGenerics>
90-
filters={memoizedFilters}
91-
onSelect={(channel) => {
92-
setChannel(channel);
93-
navigation.navigate('Channel');
94-
}}
95-
options={options}
96-
sort={sort}
97-
/>
98-
</View>
99-
</Chat>
87+
<View style={{ height: '100%' }}>
88+
<ChannelList<StreamChatGenerics>
89+
filters={memoizedFilters}
90+
onSelect={(channel) => {
91+
setChannel(channel);
92+
navigation.navigate('Channel');
93+
}}
94+
options={options}
95+
sort={sort}
96+
/>
97+
</View>
10098
);
10199
};
102100

@@ -126,21 +124,19 @@ const ChannelScreen: React.FC<ChannelScreenProps> = ({ navigation }) => {
126124

127125
return (
128126
<SafeAreaView>
129-
<Chat client={chatClient} i18nInstance={streami18n}>
130-
<Channel channel={channel} keyboardVerticalOffset={headerHeight} thread={thread}>
131-
<View style={{ flex: 1 }}>
132-
<MessageList<StreamChatGenerics>
133-
onThreadSelect={(thread) => {
134-
setThread(thread);
135-
if (channel?.id) {
136-
navigation.navigate('Thread');
137-
}
138-
}}
139-
/>
140-
<MessageInput />
141-
</View>
142-
</Channel>
143-
</Chat>
127+
<Channel channel={channel} keyboardVerticalOffset={headerHeight} thread={thread}>
128+
<View style={{ flex: 1 }}>
129+
<MessageList<StreamChatGenerics>
130+
onThreadSelect={(thread) => {
131+
setThread(thread);
132+
if (channel?.id) {
133+
navigation.navigate('Thread');
134+
}
135+
}}
136+
/>
137+
<MessageInput />
138+
</View>
139+
</Channel>
144140
</SafeAreaView>
145141
);
146142
};
@@ -163,18 +159,16 @@ const ThreadScreen: React.FC<ThreadScreenProps> = ({ navigation }) => {
163159

164160
return (
165161
<SafeAreaView>
166-
<Chat client={chatClient} i18nInstance={streami18n}>
167-
<Channel channel={channel} keyboardVerticalOffset={headerHeight} thread={thread} threadList>
168-
<View
169-
style={{
170-
flex: 1,
171-
justifyContent: 'flex-start',
172-
}}
173-
>
174-
<Thread<StreamChatGenerics> onThreadDismount={() => setThread(null)} />
175-
</View>
176-
</Channel>
177-
</Chat>
162+
<Channel channel={channel} keyboardVerticalOffset={headerHeight} thread={thread} threadList>
163+
<View
164+
style={{
165+
flex: 1,
166+
justifyContent: 'flex-start',
167+
}}
168+
>
169+
<Thread<StreamChatGenerics> onThreadDismount={() => setThread(null)} />
170+
</View>
171+
</Channel>
178172
</SafeAreaView>
179173
);
180174
};
@@ -234,34 +228,36 @@ const App = () => {
234228
i18nInstance={streami18n}
235229
value={{ style: theme }}
236230
>
237-
{clientReady && (
238-
<Stack.Navigator
239-
initialRouteName='ChannelList'
240-
screenOptions={{
241-
headerTitleStyle: { alignSelf: 'center', fontWeight: 'bold' },
242-
}}
243-
>
244-
<Stack.Screen
245-
component={ChannelScreen}
246-
name='Channel'
247-
options={() => ({
248-
headerBackTitle: 'Back',
249-
headerRight: () => <></>,
250-
headerTitle: channel?.data?.name,
251-
})}
252-
/>
253-
<Stack.Screen
254-
component={ChannelListScreen}
255-
name='ChannelList'
256-
options={{ headerTitle: 'Channel List' }}
257-
/>
258-
<Stack.Screen
259-
component={ThreadScreen}
260-
name='Thread'
261-
options={() => ({ headerLeft: () => <></> })}
262-
/>
263-
</Stack.Navigator>
264-
)}
231+
<Chat client={chatClient} i18nInstance={streami18n}>
232+
{clientReady && (
233+
<Stack.Navigator
234+
initialRouteName='ChannelList'
235+
screenOptions={{
236+
headerTitleStyle: { alignSelf: 'center', fontWeight: 'bold' },
237+
}}
238+
>
239+
<Stack.Screen
240+
component={ChannelScreen}
241+
name='Channel'
242+
options={() => ({
243+
headerBackTitle: 'Back',
244+
headerRight: () => <></>,
245+
headerTitle: channel?.data?.name,
246+
})}
247+
/>
248+
<Stack.Screen
249+
component={ChannelListScreen}
250+
name='ChannelList'
251+
options={{ headerTitle: 'Channel List' }}
252+
/>
253+
<Stack.Screen
254+
component={ThreadScreen}
255+
name='Thread'
256+
options={() => ({ headerLeft: () => <></> })}
257+
/>
258+
</Stack.Navigator>
259+
)}
260+
</Chat>
265261
</OverlayProvider>
266262
</GestureHandlerRootView>
267263
</AppContext.Provider>

package/src/components/Message/MessageSimple/ReactionList.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -283,13 +283,11 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
283283
const {
284284
message: prevMessage,
285285
messageContentWidth: prevMessageContentWidth,
286-
reactions: prevReactions,
287286
targetedMessage: prevTargetedMessage,
288287
} = prevProps;
289288
const {
290289
message: nextMessage,
291290
messageContentWidth: nextMessageContentWidth,
292-
reactions: nextReactions,
293291
targetedMessage: nextTargetedMessage,
294292
} = nextProps;
295293

@@ -304,14 +302,14 @@ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = Default
304302

305303
if (!targetedMessageEqual) return false;
306304

307-
const reactionsEqual =
308-
prevReactions.length === nextReactions.length &&
309-
prevReactions.every(
310-
(latestReaction, index) =>
311-
nextReactions[index].own === latestReaction.own &&
312-
nextReactions[index].type === latestReaction.type,
313-
);
314-
if (!reactionsEqual) return false;
305+
const latestReactionsEqual =
306+
Array.isArray(prevMessage.latest_reactions) && Array.isArray(nextMessage.latest_reactions)
307+
? prevMessage.latest_reactions.length === nextMessage.latest_reactions.length &&
308+
prevMessage.latest_reactions.every(
309+
({ type }, index) => type === nextMessage.latest_reactions?.[index].type,
310+
)
311+
: prevMessage.latest_reactions === nextMessage.latest_reactions;
312+
if (!latestReactionsEqual) return false;
315313

316314
return true;
317315
};

package/src/components/Message/hooks/useCreateMessageContext.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ export const useCreateMessageContext = <
4848
const reactionsValue = reactions.map(({ own, type }) => `${own}${type}`).join();
4949
const latestReactions = message.latest_reactions ? message.latest_reactions : undefined;
5050
const readBy = isMessageWithStylesReadByAndDateSeparator(message) && message.readBy;
51-
const messageValue = `${latestReactions ? latestReactions.map(({ type }) => type).join() : ''}${
52-
message.updated_at
53-
}${message.deleted_at}${readBy}${message.status}${message.type}${message.text}${
54-
message.reply_count
55-
}`;
51+
const messageValue = `${
52+
latestReactions ? latestReactions.map(({ type, user }) => `${type}${user?.id}`).join() : ''
53+
}${message.updated_at}${message.deleted_at}${readBy}${message.status}${message.type}${
54+
message.text
55+
}${message.reply_count}`;
5656
const membersValue = JSON.stringify(members);
5757

5858
const quotedMessageDeletedValue = message.quoted_message?.deleted_at;

0 commit comments

Comments
 (0)