# React Development Guide for Lin Project ## Overview This guide documents the React development patterns, best practices, and conventions used in the Lin project. It serves as a reference for current and future developers working on the frontend. ## Project Structure The frontend follows a component-based architecture with clear separation of concerns: ``` frontend/ ├── src/ │ ├── components/ # Reusable UI components │ │ ├── Header/ # Header component │ │ ├── Sidebar/ # Sidebar navigation │ │ └── ... # Other reusable components │ ├── pages/ # Page-level components │ ├── services/ # API service layer │ ├── store/ # Redux store configuration │ ├── App.jsx # Root component │ └── index.jsx # Entry point ├── public/ # Static assets └── package.json # Dependencies and scripts ``` ## Core Technologies - React 18+ with Hooks - React Router v6 for routing - Redux Toolkit for state management - Axios for HTTP requests - Tailwind CSS for styling - Material Icons for icons ## Component Development Patterns ### Functional Components with Hooks All components are implemented as functional components using React hooks: ```jsx import React, { useState, useEffect } from 'react'; const MyComponent = ({ prop1, prop2 }) => { const [state, setState] = useState(initialValue); useEffect(() => { // Side effects }, [dependencies]); return (
{/* JSX */}
); }; export default MyComponent; ``` ### Component Structure 1. **Imports** - All necessary imports at the top 2. **Component Definition** - Functional component with destructured props 3. **State Management** - useState, useEffect, and custom hooks 4. **Helper Functions** - Small utility functions within the component 5. **JSX Return** - Clean, semantic HTML with Tailwind classes 6. **Export** - Default export of the component ### State Management #### Local Component State Use `useState` for local component state: ```jsx const [isOpen, setIsOpen] = useState(false); const [data, setData] = useState([]); const [loading, setLoading] = useState(false); ``` #### Global State (Redux) Use Redux Toolkit for global state management. Structure slices by feature: ```jsx // store/reducers/featureSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; export const fetchFeatureData = createAsyncThunk( 'feature/fetchData', async (params) => { const response = await api.getFeatureData(params); return response.data; } ); const featureSlice = createSlice({ name: 'feature', initialState: { items: [], loading: false, error: null }, reducers: { clearError: (state) => { state.error = null; } }, extraReducers: (builder) => { builder .addCase(fetchFeatureData.pending, (state) => { state.loading = true; }) .addCase(fetchFeatureData.fulfilled, (state, action) => { state.loading = false; state.items = action.payload; }) .addCase(fetchFeatureData.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }); } }); export const { clearError } = featureSlice.actions; export default featureSlice.reducer; ``` ### Props and Prop Types Destructure props in the component signature and provide default values when appropriate: ```jsx const MyComponent = ({ title, items = [], isLoading = false, onAction = () => {} }) => { // Component implementation }; ``` ### Event Handling Use inline arrow functions or separate handler functions: ```jsx // Inline // Separate function const handleDelete = (id) => { dispatch(deleteItem(id)); }; ``` ## Styling with Tailwind CSS The project uses Tailwind CSS for styling. Follow these conventions: ### Class Organization 1. **Layout classes** (flex, grid, etc.) first 2. **Positioning** (relative, absolute, etc.) 3. **Sizing** (w-, h-, etc.) 4. **Spacing** (m-, p-, etc.) 5. **Typography** (text-, font-, etc.) 6. **Visual** (bg-, border-, shadow-, etc.) 7. **Interactive states** (hover:, focus:, etc.) ```jsx
{/* Content */}
``` ### Responsive Design Use Tailwind's responsive prefixes (sm:, md:, lg:, xl:) for responsive styles: ```jsx
{/* Content */}
{/* Content */}
``` ### Custom Classes For complex components, use component-specific classes in conjunction with Tailwind: ```jsx ` nav-link group relative flex items-center px-3 py-2.5 text-sm font-medium rounded-lg transition-all duration-200 ease-in-out ${isActive ? 'bg-gradient-to-r from-primary-600 to-primary-700 text-white' : 'text-secondary-700 hover:bg-accent-100' } `} > ``` ## Routing Use React Router v6 for navigation: ```jsx import { Routes, Route, useNavigate, useLocation } from 'react-router-dom'; // In App.jsx } /> } /> } /> } /> // In components const navigate = useNavigate(); const location = useLocation(); // Navigation navigate('/dashboard'); // Check current route if (location.pathname === '/dashboard') { // Do something } ``` ## API Integration ### Service Layer Create service functions for API calls: ```jsx // services/api.js import axios from 'axios'; const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:5000'; const api = axios.create({ baseURL: API_BASE_URL, timeout: 10000, }); // Request interceptor api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }); // Response interceptor api.interceptors.response.use( (response) => response, (error) => { if (error.response?.status === 401) { // Handle unauthorized access localStorage.removeItem('token'); window.location.href = '/login'; } return Promise.reject(error); } ); export default api; // services/featureService.js import api from './api'; export const getFeatures = async () => { const response = await api.get('/api/features'); return response.data; }; export const createFeature = async (data) => { const response = await api.post('/api/features', data); return response.data; }; ``` ### Async Operations with Redux Thunks Use createAsyncThunk for asynchronous operations: ```jsx // In slice export const fetchData = createAsyncThunk( 'feature/fetchData', async (_, { rejectWithValue }) => { try { const data = await featureService.getFeatures(); return data; } catch (error) { return rejectWithValue(error.response.data); } } ); // In component const dispatch = useDispatch(); const { items, loading, error } = useSelector(state => state.feature); useEffect(() => { dispatch(fetchData()); }, [dispatch]); ``` ## Accessibility (a11y) Implement proper accessibility features: 1. **Semantic HTML** - Use appropriate HTML elements 2. **ARIA attributes** - When needed for dynamic content 3. **Keyboard navigation** - Ensure all interactive elements are keyboard accessible 4. **Focus management** - Proper focus handling for modals, dropdowns, etc. 5. **Screen reader support** - Use aria-label, aria-describedby, etc. ```jsx ``` ## Performance Optimization ### Memoization Use React.memo for components that render frequently: ```jsx const MyComponent = React.memo(({ data, onUpdate }) => { // Component implementation }); export default MyComponent; ``` ### useCallback and useMemo Optimize expensive calculations and callback functions: ```jsx const expensiveValue = useMemo(() => { return computeExpensiveValue(data); }, [data]); const handleClick = useCallback((id) => { dispatch(action(id)); }, [dispatch]); ``` ### Lazy Loading Use React.lazy for code splitting: ```jsx import { lazy, Suspense } from 'react'; const LazyComponent = lazy(() => import('./components/MyComponent')); Loading...}> ``` ## Error Handling ### Error Boundaries Implement error boundaries for catching JavaScript errors: ```jsx class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; } static getDerivedStateFromError(error) { return { hasError: true }; } componentDidCatch(error, errorInfo) { console.error('Error caught by boundary:', error, errorInfo); } render() { if (this.state.hasError) { return

Something went wrong.

; } return this.props.children; } } // Usage ``` ### API Error Handling Handle API errors gracefully: ```jsx const [error, setError] = useState(null); const handleSubmit = async (data) => { try { setError(null); const result = await api.createItem(data); // Handle success } catch (err) { setError(err.response?.data?.message || 'An error occurred'); } }; {error && (
{error}
)} ``` ## Testing ### Unit Testing Use Jest and React Testing Library for unit tests: ```jsx import { render, screen, fireEvent } from '@testing-library/react'; import MyComponent from './MyComponent'; test('renders component with title', () => { render(); expect(screen.getByText('Test Title')).toBeInTheDocument(); }); test('calls onClick when button is clicked', () => { const handleClick = jest.fn(); render(); fireEvent.click(screen.getByRole('button')); expect(handleClick).toHaveBeenCalledTimes(1); }); ``` ### Redux Testing Test Redux slices and async thunks: ```jsx import featureReducer, { fetchData } from './featureSlice'; test('handles fulfilled fetch data', () => { const initialState = { items: [], loading: false, error: null }; const data = [{ id: 1, name: 'Test' }]; const action = { type: fetchData.fulfilled, payload: data }; const state = featureReducer(initialState, action); expect(state.items).toEqual(data); expect(state.loading).toBe(false); }); ``` ## Mobile Responsiveness ### Touch Optimization Add touch-specific classes and handlers: ```jsx ``` ### Responsive Breakpoints Use Tailwind's responsive utilities for different screen sizes: - Mobile: Default styles (0-767px) - Tablet: `sm:` (768px+) and `md:` (1024px+) - Desktop: `lg:` (1280px+) and `xl:` (1536px+) ### Mobile-First Approach Start with mobile styles and enhance for larger screens: ```jsx
{/* Content that stacks on mobile, side-by-side on desktop */}
``` ## Best Practices ### Component Design 1. **Single Responsibility** - Each component should have one clear purpose 2. **Reusability** - Design components to be reusable across the application 3. **Composition** - Build complex UIs by composing simpler components 4. **Controlled Components** - Prefer controlled components for form elements 5. **Props Drilling** - Use context or Redux to avoid excessive prop drilling ### Code Organization 1. **Consistent Naming** - Use consistent naming conventions (PascalCase for components) 2. **Logical Grouping** - Group related files in directories 3. **Export Strategy** - Use default exports for components, named exports for utilities 4. **Import Organization** - Group imports logically (external, internal, styles) ### Performance 1. **Bundle Size** - Monitor bundle size and optimize when necessary 2. **Rendering** - Use React.memo, useMemo, and useCallback appropriately 3. **API Calls** - Implement caching and pagination where appropriate 4. **Images** - Optimize images and use lazy loading ### Security 1. **XSS Prevention** - React automatically escapes content, but be careful with dangerouslySetInnerHTML 2. **Token Storage** - Store JWT tokens securely (HttpOnly cookies or secure localStorage) 3. **Input Validation** - Validate and sanitize user inputs 4. **CORS** - Ensure proper CORS configuration on the backend This guide should help maintain consistency and quality across the React frontend implementation in the Lin project.