# Code Cleanup Guide This guide documents the cleanup patterns and best practices applied to the codebase, starting with `GroceryList.jsx`. Use this as a reference for maintaining consistent, clean, and readable code across all files. ## Table of Contents 1. [Spacing & Organization](#spacing--organization) 2. [Comment Formatting](#comment-formatting) 3. [Code Simplification](#code-simplification) 4. [React Performance Patterns](#react-performance-patterns) 5. [Cleanup Checklist](#cleanup-checklist) --- ## Spacing & Organization ### Two-Line Separation Use **2 blank lines** to separate logical groups and functions. **Before:** ```javascript const handleAdd = async (itemName, quantity) => { // function body }; const handleBought = async (id) => { // function body }; ``` **After:** ```javascript const handleAdd = async (itemName, quantity) => { // function body }; const handleBought = async (id) => { // function body }; ``` ### Logical Grouping Organize code into clear sections: - State declarations - Data loading functions - Computed values (useMemo) - Event handlers grouped by functionality - Helper functions - Render logic --- ## Comment Formatting ### Section Headers Use the `=== Section Name ===` format for major sections, followed by 2 blank lines before the next code block. **Pattern:** ```javascript // === State === const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); // === Data Loading === const loadItems = async () => { // implementation }; // === Event Handlers === const handleClick = () => { // implementation }; ``` ### Common Section Names - `=== State ===` - `=== Data Loading ===` - `=== Computed Values ===` or `=== Sorted Items Computation ===` - `=== Event Handlers ===` or specific groups like `=== Item Addition Handlers ===` - `=== Helper Functions ===` - `=== Render ===` --- ## Code Simplification ### 1. Optional Chaining Replace `&&` null checks with optional chaining when accessing nested properties. **Before:** ```javascript if (existingItem && existingItem.bought === false) { // do something } ``` **After:** ```javascript if (existingItem?.bought === false) { // do something } ``` **When to use:** - Accessing properties on potentially undefined/null objects - Checking nested properties: `user?.profile?.name` - Method calls: `item?.toString?.()` **When NOT to use:** - When you need to check if the object exists first (use explicit check) - For boolean coercion: `if (item)` is clearer than `if (item?.)` --- ### 2. Ternary Operators Use ternary operators for simple conditional assignments and returns. **Before:** ```javascript let result; if (condition) { result = "yes"; } else { result = "no"; } ``` **After:** ```javascript const result = condition ? "yes" : "no"; ``` **When to use:** - Simple conditional assignments - Inline JSX conditionals - Return statements with simple conditions **When NOT to use:** - Complex multi-line logic (use if/else for readability) - Nested ternaries (hard to read) --- ### 3. Early Returns Use early returns to reduce nesting. **Before:** ```javascript const handleSuggest = async (text) => { if (text.trim()) { // long implementation } else { setSuggestions([]); setButtonText("Add Item"); } }; ``` **After:** ```javascript const handleSuggest = async (text) => { if (!text.trim()) { setSuggestions([]); setButtonText("Add Item"); return; } // main implementation without nesting }; ``` --- ### 4. Destructuring Use destructuring for cleaner variable access. **Before:** ```javascript const username = user.username; const email = user.email; const role = user.role; ``` **After:** ```javascript const { username, email, role } = user; ``` --- ### 5. Array Methods Over Loops Prefer array methods (`.map()`, `.filter()`, `.find()`) over traditional loops. **Before:** ```javascript const activeItems = []; for (let i = 0; i < items.length; i++) { if (!items[i].bought) { activeItems.push(items[i]); } } ``` **After:** ```javascript const activeItems = items.filter(item => !item.bought); ``` --- ## React Performance Patterns ### 1. useCallback for Event Handlers Wrap event handlers in `useCallback` to prevent unnecessary re-renders of child components. ```javascript const handleBought = useCallback(async (id, quantity) => { await markBought(id); setItems(prevItems => prevItems.filter(item => item.id !== id)); loadRecentlyBought(); }, []); // Add dependencies if needed ``` **When to use:** - Handler functions passed as props to memoized child components - Functions used as dependencies in other hooks - Functions in frequently re-rendering components --- ### 2. useMemo for Expensive Computations Use `useMemo` for computationally expensive operations or large transformations. ```javascript const sortedItems = useMemo(() => { const sorted = [...items]; if (sortMode === "az") { sorted.sort((a, b) => a.item_name.localeCompare(b.item_name)); } return sorted; }, [items, sortMode]); ``` **When to use:** - Sorting/filtering large arrays - Complex calculations - Derived state that's expensive to compute --- ### 3. React.memo for Components Wrap components with `React.memo` and provide custom comparison functions to prevent unnecessary re-renders. ```javascript const GroceryListItem = React.memo( ({ item, onClick, onLongPress }) => { // component implementation }, (prevProps, nextProps) => { return ( prevProps.id === nextProps.id && prevProps.item_name === nextProps.item_name && prevProps.quantity === nextProps.quantity && prevProps.item_image === nextProps.item_image ); } ); ``` **When to use:** - List item components that render frequently - Components with stable props - Pure components (output depends only on props) --- ### 4. In-Place State Updates Update specific items in state instead of reloading entire datasets. **Before:** ```javascript const handleUpdate = async (id, newData) => { await updateItem(id, newData); loadItems(); // Reloads entire list from server }; ``` **After:** ```javascript const handleUpdate = useCallback(async (id, newData) => { const response = await updateItem(id, newData); setItems(prevItems => prevItems.map(item => item.id === id ? { ...item, ...response.data } : item ) ); }, []); ``` **Benefits:** - Faster updates (no server round-trip for entire list) - Preserves scroll position - Better user experience (no full re-render) --- ## Cleanup Checklist Use this checklist when cleaning up a file: ### Structure & Organization - [ ] Group related state variables together - [ ] Use 2-line spacing between logical sections - [ ] Add section comments using `=== Format ===` - [ ] Order sections logically (state → data loading → computed → handlers → helpers → render) ### Code Simplification - [ ] Replace `&&` null checks with optional chaining where appropriate - [ ] Convert simple if/else to ternary operators - [ ] Use early returns to reduce nesting - [ ] Apply destructuring for cleaner variable access - [ ] Use array methods instead of loops ### React Performance - [ ] Wrap stable event handlers in `useCallback` - [ ] Use `useMemo` for expensive computations - [ ] Consider `React.memo` for list items or frequently re-rendering components - [ ] Update state in-place instead of reloading from server ### Consistency - [ ] Check naming conventions (camelCase for functions/variables) - [ ] Ensure consistent spacing and indentation - [ ] Remove unused imports and variables - [ ] Remove console.logs (except intentional debugging aids) ### Testing After Cleanup - [ ] Verify no functionality broke - [ ] Check that performance improved (using React DevTools Profiler) - [ ] Test all interactive features - [ ] Verify mobile/responsive behavior still works --- ## Example: Before & After ### Before Cleanup ```javascript import { useState, useEffect } from "react"; export default function MyComponent() { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const loadItems = async () => { setLoading(true); const res = await getItems(); setItems(res.data); setLoading(false); }; useEffect(() => { loadItems(); }, []); const handleUpdate = async (id, data) => { await updateItem(id, data); loadItems(); }; const handleDelete = async (id) => { await deleteItem(id); loadItems(); }; if (loading) return

Loading...

; return (
{items.map(item => ( ))}
); } ``` ### After Cleanup ```javascript import { useCallback, useEffect, useMemo, useState } from "react"; export default function MyComponent() { // === State === const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); // === Data Loading === const loadItems = async () => { setLoading(true); const res = await getItems(); setItems(res.data); setLoading(false); }; useEffect(() => { loadItems(); }, []); // === Event Handlers === const handleUpdate = useCallback(async (id, data) => { const response = await updateItem(id, data); setItems(prevItems => prevItems.map(item => item.id === id ? { ...item, ...response.data } : item ) ); }, []); const handleDelete = useCallback(async (id) => { await deleteItem(id); setItems(prevItems => prevItems.filter(item => item.id !== id)); }, []); // === Render === if (loading) return

Loading...

; return (
{items.map(item => ( ))}
); } ``` **Key improvements:** 1. Added section comments for clarity 2. Proper 2-line spacing between sections 3. Wrapped handlers in `useCallback` for performance 4. In-place state updates instead of reloading entire list 5. Better import organization --- ## Additional Resources - [React Performance Optimization](https://react.dev/learn/render-and-commit) - [useCallback Hook](https://react.dev/reference/react/useCallback) - [useMemo Hook](https://react.dev/reference/react/useMemo) - [React.memo](https://react.dev/reference/react/memo) --- ## Notes - **Don't over-optimize**: Not every component needs `useCallback`/`useMemo`. Apply these patterns when you have measurable performance issues or when working with large lists. - **Readability first**: If a simplification makes code harder to understand, skip it. Code should be optimized for human reading first. - **Test thoroughly**: Always test after cleanup to ensure no functionality broke. - **Incremental cleanup**: Don't try to clean up everything at once. Focus on one file at a time. --- **Last Updated**: Based on GroceryList.jsx cleanup (January 2026)