diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 00000000..2d62013f --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2026-02-18 - [React Performance: Context Memoization & Derived Variables] +**Learning:** React Context providers that pass object literals as values cause all consumers to re-render whenever the provider re-renders, even if the data hasn't changed. Similarly, using `useState` + `useEffect` for simple UI logic (like `showEmptyScreen`) introduces an extra render cycle and unnecessary state management overhead. +**Action:** Always memoize Context provider values using `useMemo` and prefer derived variables over `useState` for simple data transformations from existing state/props. diff --git a/components/chat.tsx b/components/chat.tsx index e675f124..d31f8cd5 100644 --- a/components/chat.tsx +++ b/components/chat.tsx @@ -36,7 +36,6 @@ export function Chat({ id }: ChatProps) { const { isUsageOpen } = useUsageToggle(); const { isCalendarOpen } = useCalendarToggle() const [input, setInput] = useState('') - const [showEmptyScreen, setShowEmptyScreen] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const [suggestions, setSuggestions] = useState(null) const chatPanelRef = useRef(null); @@ -49,9 +48,8 @@ export function Chat({ id }: ChatProps) { chatPanelRef.current?.submitForm(); }; - useEffect(() => { - setShowEmptyScreen(messages.length === 0) - }, [messages]) + // Optimization: Use a derived variable instead of state to avoid unnecessary render cycles + const showEmptyScreen = messages.length === 0 useEffect(() => { // Check if device is mobile diff --git a/components/map/map-data-context.tsx b/components/map/map-data-context.tsx index 9b102547..72800b69 100644 --- a/components/map/map-data-context.tsx +++ b/components/map/map-data-context.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { createContext, useContext, useState, ReactNode } from 'react'; +import React, { createContext, useContext, useState, ReactNode, useMemo } from 'react'; // Define the shape of the map data you want to share export interface CameraState { center: { lat: number; lng: number }; @@ -41,8 +41,11 @@ const MapDataContext = createContext(undefined); export const MapDataProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const [mapData, setMapData] = useState({ drawnFeatures: [], markers: [] }); + // Memoize the context value to prevent unnecessary re-renders of consumers + const value = useMemo(() => ({ mapData, setMapData }), [mapData]); + return ( - + {children} );