-
Hello, I would like to ask for your assistance in understanding why I am experiencing unnecessary re-rendering of the component every time I click on the same link. This issue seems to be caused by the use of the here a short case demonstration
Parent component: export const Conversation = () => {
// const { id } = useParams() as { id: string };
const setChat = useChat((state) => state.actions.setChat);
// const navigate = useNavigate();
const { isLoading, isError, isRefetching, refetch, data } = useQuery(({ signal }) => conversationApi.get('67096041d913474deb2ea5bc', signal), {
keys: [],
retry: 5,
retryDelay: 2000,
onSelect: ({ messages, ...data }) => data,
onSuccess: ({ messages }) => {
setChat({
messages,
params: {
id: '67096041d913474deb2ea5bc',
type: SourceRefPath.CONVERSATION,
query: { recipientId: '67096041d913474deb2ea5bc', session_id: useSocket.getState().session_id }
}
});
},
});
if (isLoading) return <ChatSkeleton />;
if (isError) {
return (
<OutletError
title='Something went wrong'
description='Cannot load conversation'
callToAction={
<Button onClick={refetch} className='mt-5' disabled={isRefetching}>
{isRefetching ? <Loader2 className='w-6 h-6 animate-spin' /> : 'try again'}
</Button>
}
/>
);
}
return (
// <ConversationProvider conversation={data}>
<Content />
// </ConversationProvider>
);
}; Content: export const Content = () => {
// const { _id, isInitiatorBlocked, isRecipientBlocked, recipient, isRecipientTyping, handleTypingStatus } = useConversation(useShallow(contentSelector));
const showDetails = useChat((state) => state.showDetails);
// const description = getConversationDescription({ data: { recipient, isInitiatorBlocked, isRecipientBlocked }, isRecipientTyping });
console.log('rerender')
return (
<OutletContainer>
test
{/* <div className='flex-1 flex flex-col'>
<OutletHeader
name={recipient.name}
isOfficial={recipient.isOfficial}
description={description}
dropdownMenu={<ConversationDDM />}
/>
<MessagesList getPreviousMessages={(id, cursor) => conversationApi.getPreviousMessages(id, cursor)} />
<SendMessage
handleTypingStatus={handleTypingStatus()}
restrictMessaging={[
{
reason: !!(isInitiatorBlocked || isRecipientBlocked),
message: isRecipientBlocked ? `You blocked ${recipient.name}` : `${recipient.name} has restricted incoming messages`
},
{
reason: !_id && recipient.isPrivate,
message: `${recipient.name} does not accept new messages`
}
]}
/>
</div>
{showDetails && (
<OutletDetails
title='User Info'
name={recipient.name}
avatarUrl={recipient.avatar?.url}
description={description}
info={[
{ data: recipient.status, type: OutletDetailsTypes.BIO },
{ data: recipient.login, type: OutletDetailsTypes.LOGIN },
]}
/>
)} */}
</OutletContainer>
);
}; NavLink i use to navigate: export const ConversationItem = ({ feedItem: { item } }: { feedItem: ExctactLocalFeedItem<FeedTypes.CONVERSATION> }) => {
const recipient = item.recipient;
const draft = useLayout((state) => state.drafts).get(recipient._id);
return (
<li>
<NavLink
to={`/conversation/${recipient._id}`}
className={({ isActive }) =>
cn(
'flex items-center gap-5 p-2 rounded-lg transition-colors duration-200 ease-in-out',
isActive
? 'dark:bg-primary-dark-50 bg-primary-gray/10'
: 'dark:hover:bg-primary-dark-50/30 hover:bg-primary-gray/5'
)
}
>
// jsx
</NavLink>
</li>
);
}; |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
All RR and Remix hooks depends on the same React context And while the navigate function is stable between renders meaning any effect depending on it won't trigger again, the way useContext works in React doesn't allow to pick only part of the state This behavior cause that if the state is large any small change to it will cause a re render of any component accessing it And when you navigate from one page to another there are many states inside this context changing like the navigation.status, the loader data, the route params, etc all any change there will cause a re render |
Beta Was this translation helpful? Give feedback.
All RR and Remix hooks depends on the same React context
And while the navigate function is stable between renders meaning any effect depending on it won't trigger again, the way useContext works in React doesn't allow to pick only part of the state
This behavior cause that if the state is large any small change to it will cause a re render of any component accessing it
And when you navigate from one page to another there are many states inside this context changing like the navigation.status, the loader data, the route params, etc all any change there will cause a re render