useAppStore
is a Zustand Store.
I made 3 assumptions based on my understand of React hooks (Please correct me if any of them is wrong)
const MessageList: React.FC<MessageListProps> = ({ popupId }) => {
const {
popups,
isLoading,
liveResponse: response,
liveAttachments,
updateVisibleMessages,
} = useAppStore();
popups
is a list ofPopupState
. whenever I change a popup by id, for example atPopupState.position.x
, I create a new instance of the arraypopups
and change the popup state (new instance too) of that id. (immutability). Since I changed the array of popups, all popups on screen will re-render, which is extremely wasteful because I only want to update position x of one popup by id. Is this correct?If change the code like this, it will render only when those fields changes, which is the most efficient approach to avoid unnecessary re-render. Is my understanding correct?
const MessageList: React.FC<MessageListProps> = ({ popupId }) => { const themeStyle = useAppStore((state) => state.popups.find((p) => p.id === popupId)?.themeStyle); const currentNodeId = useAppStore((state) => state.popups.find((p) => p.id === popupId)?.currentNodeId); const messagesMap = useAppStore((state) => state.popups.find((p) => p.id === popupId)?.messagesMap); const lastUserMessage = useAppStore((state) => state.popups.find((p) => p.id === popupId)?.lastUserMessage); const cachedVisibleMessages = useAppStore((state) => state.popups.find((p) => p.id === popupId)?.cachedVisibleMessages);
I hate repeating the
state.popups.find((p) => p.id === popupId)
so many times, but if I change the code like below, I lose all optimization again. In fact it will be worse because I create a new object instance to wrap the value and when React compares the previous and current value of the hook, it will always think that the state changed even though the fields values itself didn't change. Is that correct? React does not do deep comparison?const { position, title } = useAppStore((state) => ({ position: state.popups[popupId]?.position, title: state.popups[popupId]?.title, }));
Question: If all my assumptions are correct, how to make the code in 2. look more compact and non-repetitive (DRY). Is caching it in the store the only solution?