Skip to content

Commit 7a8f009

Browse files
committed
fix: add back react memo
1 parent 31f88aa commit 7a8f009

File tree

4 files changed

+118
-15
lines changed

4 files changed

+118
-15
lines changed

package/src/components/AutoCompleteInput/AutoCompleteInput.tsx

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import {
1111

1212
import { CustomDataManagerState, TextComposerState } from 'stream-chat';
1313

14-
import { useChannelContext } from '../../contexts/channelContext/ChannelContext';
14+
import {
15+
ChannelContextValue,
16+
useChannelContext,
17+
} from '../../contexts/channelContext/ChannelContext';
1518
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
1619
import {
1720
MessageInputContextValue,
@@ -25,16 +28,19 @@ import {
2528

2629
import { useStateStore } from '../../hooks/useStateStore';
2730

28-
type AutoCompleteInputProps = TextInputProps &
29-
Partial<Pick<MessageInputContextValue, 'setInputBoxRef'>> &
30-
Partial<Pick<TranslationContextValue, 't'>> & {
31+
type AutoCompleteInputPropsWithContext = TextInputProps &
32+
Pick<ChannelContextValue, 'channel'> &
33+
Pick<MessageInputContextValue, 'setInputBoxRef'> &
34+
Pick<TranslationContextValue, 't'> & {
3135
/**
3236
* This is currently passed in from MessageInput to avoid rerenders
3337
* that would happen if we put this in the MessageInputContext
3438
*/
3539
cooldownActive?: boolean;
3640
};
3741

42+
type AutoCompleteInputProps = Partial<AutoCompleteInputPropsWithContext>;
43+
3844
const textComposerStateSelector = (state: TextComposerState) => ({
3945
text: state.text,
4046
});
@@ -45,20 +51,14 @@ const customComposerDataSelector = (state: CustomDataManagerState) => ({
4551

4652
const MAX_NUMBER_OF_LINES = 5;
4753

48-
export const AutoCompleteInput = (props: AutoCompleteInputProps) => {
49-
const { cooldownActive = false, setInputBoxRef: propSetInputBoxRef, t: propT, ...rest } = props;
54+
const AutoCompleteInputWithContext = (props: AutoCompleteInputPropsWithContext) => {
55+
const { channel, cooldownActive = false, setInputBoxRef, t, ...rest } = props;
5056
const [localText, setLocalText] = useState('');
5157
const [textHeight, setTextHeight] = useState(0);
5258
const messageComposer = useMessageComposer();
5359
const { customDataManager, textComposer } = messageComposer;
5460
const { text } = useStateStore(textComposer.state, textComposerStateSelector);
5561
const { command } = useStateStore(customDataManager.state, customComposerDataSelector);
56-
const { channel } = useChannelContext();
57-
const { setInputBoxRef: contextSetInputBoxRef } = useMessageInputContext();
58-
const { t: contextT } = useTranslationContext();
59-
60-
const setInputBoxRef = propSetInputBoxRef || contextSetInputBoxRef;
61-
const t = propT || contextT;
6262

6363
const maxMessageLength = useMemo(() => {
6464
return channel.getConfig()?.max_message_length;
@@ -142,6 +142,53 @@ export const AutoCompleteInput = (props: AutoCompleteInputProps) => {
142142
);
143143
};
144144

145+
const areEqual = (
146+
prevProps: AutoCompleteInputPropsWithContext,
147+
nextProps: AutoCompleteInputPropsWithContext,
148+
) => {
149+
const { channel: prevChannel, cooldownActive: prevCooldownActive, t: prevT } = prevProps;
150+
const { channel: nextChannel, cooldownActive: nextCooldownActive, t: nextT } = nextProps;
151+
152+
const tEqual = prevT === nextT;
153+
if (!tEqual) {
154+
return false;
155+
}
156+
157+
const cooldownActiveEqual = prevCooldownActive === nextCooldownActive;
158+
if (!cooldownActiveEqual) {
159+
return false;
160+
}
161+
162+
const channelEqual = prevChannel.cid === nextChannel.cid;
163+
if (!channelEqual) {
164+
return false;
165+
}
166+
167+
return true;
168+
};
169+
170+
const MemoizedAutoCompleteInput = React.memo(
171+
AutoCompleteInputWithContext,
172+
areEqual,
173+
) as typeof AutoCompleteInputWithContext;
174+
175+
export const AutoCompleteInput = (props: AutoCompleteInputProps) => {
176+
const { setInputBoxRef } = useMessageInputContext();
177+
const { t } = useTranslationContext();
178+
const { channel } = useChannelContext();
179+
180+
return (
181+
<MemoizedAutoCompleteInput
182+
{...{
183+
channel,
184+
setInputBoxRef,
185+
t,
186+
}}
187+
{...props}
188+
/>
189+
);
190+
};
191+
145192
const styles = StyleSheet.create({
146193
inputBox: {
147194
flex: 1,

package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const CommandsHeader: React.FC<AutoCompleteSuggestionHeaderProps> = () =>
3232
</View>
3333
);
3434
};
35+
3536
export const EmojiHeader: React.FC<AutoCompleteSuggestionHeaderProps> = ({ queryText }) => {
3637
const {
3738
theme: {
@@ -54,7 +55,7 @@ export const EmojiHeader: React.FC<AutoCompleteSuggestionHeaderProps> = ({ query
5455
);
5556
};
5657

57-
export const AutoCompleteSuggestionHeader = ({
58+
const UnMemoizedAutoCompleteSuggestionHeader = ({
5859
queryText,
5960
triggerType,
6061
}: AutoCompleteSuggestionHeaderProps) => {
@@ -67,6 +68,35 @@ export const AutoCompleteSuggestionHeader = ({
6768
}
6869
};
6970

71+
const areEqual = (
72+
prevProps: AutoCompleteSuggestionHeaderProps,
73+
nextProps: AutoCompleteSuggestionHeaderProps,
74+
) => {
75+
const { queryText: prevQueryText, triggerType: prevType } = prevProps;
76+
const { queryText: nextQueryText, triggerType: nextType } = nextProps;
77+
78+
const typeEqual = prevType === nextType;
79+
if (!typeEqual) {
80+
return false;
81+
}
82+
83+
const valueEqual = prevQueryText === nextQueryText;
84+
if (!valueEqual) {
85+
return false;
86+
}
87+
88+
return true;
89+
};
90+
91+
const MemoizedAutoCompleteSuggestionHeader = React.memo(
92+
UnMemoizedAutoCompleteSuggestionHeader,
93+
areEqual,
94+
);
95+
96+
export const AutoCompleteSuggestionHeader = (props: AutoCompleteSuggestionHeaderProps) => (
97+
<MemoizedAutoCompleteSuggestionHeader {...props} />
98+
);
99+
70100
AutoCompleteSuggestionHeader.displayName =
71101
'AutoCompleteSuggestionHeader{messageInput{suggestions{Header}}}';
72102

package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const SuggestionItem = ({
111111
}
112112
};
113113

114-
export const AutoCompleteSuggestionItem = ({
114+
const UnMemoizedAutoCompleteSuggestionItem = ({
115115
itemProps,
116116
triggerType,
117117
}: AutoCompleteSuggestionItemProps) => {
@@ -140,6 +140,32 @@ export const AutoCompleteSuggestionItem = ({
140140
);
141141
};
142142

143+
const areEqual = (
144+
prevProps: AutoCompleteSuggestionItemProps,
145+
nextProps: AutoCompleteSuggestionItemProps,
146+
) => {
147+
const { itemProps: prevItemProps, triggerType: prevType } = prevProps;
148+
const { itemProps: nextItemProps, triggerType: nextType } = nextProps;
149+
const itemPropsEqual = prevItemProps === nextItemProps;
150+
if (!itemPropsEqual) {
151+
return false;
152+
}
153+
const typeEqual = prevType === nextType;
154+
if (!typeEqual) {
155+
return false;
156+
}
157+
return true;
158+
};
159+
160+
const MemoizedAutoCompleteSuggestionItem = React.memo(
161+
UnMemoizedAutoCompleteSuggestionItem,
162+
areEqual,
163+
);
164+
165+
export const AutoCompleteSuggestionItem = (props: AutoCompleteSuggestionItemProps) => (
166+
<MemoizedAutoCompleteSuggestionItem {...props} />
167+
);
168+
143169
const styles = StyleSheet.create({
144170
args: {
145171
fontSize: 14,

package/src/components/Poll/CreatePollContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const CreatePollContent = () => {
8383
};
8484
});
8585
// eslint-disable-next-line react-hooks/exhaustive-deps
86-
}, [createPollOptionHeight, options.length]);
86+
}, [createPollOptionHeight, options]);
8787

8888
const onBackPressHandler = useCallback(() => {
8989
pollComposer.initState();

0 commit comments

Comments
 (0)