projectrules.ai

1. Code Organization and Structure:

reduxstate-managementperformance-optimizationtesting-strategiescode-structure

Description

This rule provides comprehensive guidance on Redux best practices, covering code structure, performance optimization, testing strategies, and common pitfalls to ensure robust and maintainable Redux applications.

Globs

**/*.{js,jsx,ts,tsx}
---
description: This rule provides comprehensive guidance on Redux best practices, covering code structure, performance optimization, testing strategies, and common pitfalls to ensure robust and maintainable Redux applications.
globs: **/*.{js,jsx,ts,tsx}
---

- **Introduction:** This document outlines best practices for developing applications with Redux, covering various aspects from code organization to performance optimization.

## 1. Code Organization and Structure:

- **Directory Structure:** Organize your Redux-related files in a clear and maintainable structure. A feature-based approach is recommended.
    - Example:
      
      src/
      ├── app/
      │   ├── store.js          # Redux store configuration
      ├── features/
      │   ├── counter/        # Feature module (e.g., 'counter')
      │   │   ├── counterSlice.js # Redux slice (reducers + actions)
      │   │   ├── Counter.jsx      # React component
      │   │   ├── counterAPI.js   # API interaction logic
      │   │   └── counterSelectors.js # Selectors
      │   ├── todos/
      │   │   └── ...
      ├── components/          # Reusable UI components
      ├── utils/               # Utility functions
      └── ...
      

- **File Naming Conventions:** Use consistent and descriptive names for your files.
    - Example:
        - `counterSlice.js` for Redux slice files
        - `Counter.jsx` for React components
        - `counterActions.js` or preferably included in slice
        - `counterSelectors.js` for selectors

- **Module Organization:** Group related logic into modules. Each feature should have its own directory containing its Redux slice, components, and selectors.

- **Component Architecture:** Use a container/presentational component pattern to separate data fetching and state management logic from UI rendering.
    - **Container Components:** Connect to the Redux store and pass data to presentational components.
    - **Presentational Components:** Focus on UI rendering and receive data and callbacks as props.

- **Code Splitting Strategies:** Implement code splitting to reduce the initial bundle size and improve loading times.
    - **Route-based splitting:** Load different parts of the application based on the current route.
    - **Component-based splitting:** Lazy-load components that are not immediately needed.
    - Use `React.lazy` and `<Suspense>` for component-based splitting.

## 2. Common Patterns and Anti-patterns:

- **Design Patterns:**
    - **Flux Standard Actions (FSA):** A convention for structuring Redux actions with a `type` and an optional `payload` and `error` property.
    - **Selectors:** Use selectors (e.g., with Reselect) to derive data from the Redux store efficiently.
    - **Thunks/Sagas:** Manage asynchronous side effects using Redux Thunk or Redux Saga.

- **Recommended Approaches:**
    - **Redux Toolkit:** Use Redux Toolkit to simplify Redux development and reduce boilerplate.
    - **Immutability:** Treat state as immutable and use immutable data structures or techniques to update it.
    - **Normalization:** Normalize your state to reduce data duplication and improve data consistency.

- **Anti-patterns and Code Smells:**
    - **Mutating State Directly:** Never mutate state directly. Always create new copies of objects and arrays.
    - **Putting too much logic in components:** Keep components focused on rendering. Move complex logic to reducers, selectors, or middleware.
    - **Large Reducers:** Split large reducers into smaller, more manageable reducers using `combineReducers`.
    - **Over-fetching Data:** Fetch only the data that is needed by the component. Use selectors to derive specific data subsets from the state.

- **State Management Best Practices:**
    - **Single Source of Truth:** Keep all application state in the Redux store.
    - **Predictable State Updates:** Ensure that state updates are predictable and deterministic.
    - **Minimize Global State:** Only store data that is truly global in the Redux store. Local component state should be used for UI-specific data.

- **Error Handling Patterns:**
    - **Action-based Error Handling:** Dispatch actions to indicate errors and update the state accordingly.
    - **Middleware Error Handling:** Use middleware to catch errors and log them to a central error reporting service.

## 3. Performance Considerations:

- **Optimization Techniques:**
    - **Memoization:** Use memoization to avoid unnecessary re-renders. Use `React.memo` for functional components and `shouldComponentUpdate` for class components.
    - **Selectors:** Use selectors with memoization (e.g., Reselect) to avoid recomputing derived data when the input state hasn't changed.
    - **Batch Updates:** Batch multiple state updates into a single update to reduce the number of re-renders.
    - **Debouncing/Throttling:** Use debouncing or throttling to limit the frequency of updates.

- **Memory Management:**
    - **Avoid Memory Leaks:** Clean up event listeners and timers when components unmount.
    - **Optimize Data Structures:** Use efficient data structures to reduce memory usage.

- **Rendering Optimization:**
    - **Virtualization:** Use virtualization for large lists to only render the visible items.
    - **Code Splitting:** Reduce the initial bundle size by splitting the code into smaller chunks.

- **Bundle Size Optimization:**
    - **Tree Shaking:** Remove unused code from the bundle using tree shaking.
    - **Minification:** Minify the code to reduce the bundle size.
    - **Compression:** Compress the bundle using Gzip or Brotli.

- **Lazy Loading Strategies:**
    - **Route-based Lazy Loading:** Load different routes on demand.
    - **Component-based Lazy Loading:** Load components on demand using `React.lazy`.

## 4. Security Best Practices:

- **Common Vulnerabilities:**
    - **Cross-Site Scripting (XSS):** Prevent XSS attacks by sanitizing user inputs and escaping outputs.
    - **Cross-Site Request Forgery (CSRF):** Protect against CSRF attacks by using anti-CSRF tokens.
    - **Data Injection:** Prevent data injection attacks by validating and sanitizing inputs.

- **Input Validation:**
    - **Client-Side Validation:** Validate inputs on the client-side to provide immediate feedback to the user.
    - **Server-Side Validation:** Validate inputs on the server-side to ensure data integrity.

- **Authentication and Authorization Patterns:**
    - **JWT (JSON Web Tokens):** Use JWTs for authentication and authorization.
    - **Role-Based Access Control (RBAC):** Implement RBAC to control access to different parts of the application.

- **Data Protection Strategies:**
    - **Encryption:** Encrypt sensitive data at rest and in transit.
    - **Data Masking:** Mask sensitive data to protect it from unauthorized access.

- **Secure API Communication:**
    - **HTTPS:** Use HTTPS to encrypt communication between the client and the server.
    - **API Rate Limiting:** Implement API rate limiting to prevent abuse.

## 5. Testing Approaches:

- **Unit Testing Strategies:**
    - **Test Reducers:** Test reducers to ensure that they update the state correctly.
    - **Test Actions:** Test actions to ensure that they dispatch the correct payloads.
    - **Test Selectors:** Test selectors to ensure that they derive the correct data from the state.

- **Integration Testing:**
    - **Test Components:** Test components to ensure that they render correctly and interact with the Redux store.
    - **Test Middleware:** Test middleware to ensure that they handle side effects correctly.

- **End-to-end Testing:**
    - **Test User Flows:** Test user flows to ensure that the application works as expected from the user's perspective.

- **Test Organization:**
    - **Test Directory Structure:** Organize tests in a clear and maintainable structure.
        - Example:
          
          src/
          ├── features/
          │   ├── counter/
          │   │   ├── counterSlice.test.js
          │   │   ├── Counter.test.jsx
          

- **Mocking and Stubbing:**
    - **Mock API Calls:** Mock API calls to isolate components and reducers during testing.
    - **Stub Dependencies:** Stub external dependencies to control their behavior during testing.

## 6. Common Pitfalls and Gotchas:

- **Frequent Mistakes:**
    - **Forgetting to Return State:** Reducers must always return the new state.  If no change, return the original state.
    - **Incorrectly Updating Nested Objects:** Remember to create copies of all levels when updating nested objects.
    - **Not Handling Asynchronous Actions Correctly:** Using thunks or sagas incorrectly can lead to unexpected behavior.

- **Edge Cases:**
    - **Initial State:** Ensure that the initial state is correctly defined.
    - **Handling Errors:** Handle errors gracefully and provide informative error messages.
    - **Empty States:** Handle empty states correctly to avoid unexpected behavior.

- **Version-Specific Issues:**
    - **React Redux v8 vs v7:** Be aware of the changes introduced in React Redux v8, such as the improved performance and the new `useSyncExternalStore` hook.

- **Compatibility Concerns:**
    - **Browser Compatibility:** Ensure that the application works correctly in all supported browsers.
    - **Device Compatibility:** Ensure that the application works correctly on all supported devices.

- **Debugging Strategies:**
    - **Redux DevTools:** Use the Redux DevTools extension to inspect the state and track actions.
    - **Console Logging:** Use console logging to debug code and track state changes.
    - **Debugging Tools:** Use browser debugging tools to step through code and inspect variables.

## 7. Tooling and Environment:

- **Recommended Development Tools:**
    - **Redux DevTools Extension:** Inspect Redux state and actions.
    - **VS Code with Redux Extension:** Provides code completion, linting, and debugging support for Redux.

- **Build Configuration:**
    - **Webpack/Parcel/Rollup:** Use a module bundler to bundle the code and optimize it for production.
    - **Babel:** Use Babel to transpile the code to older versions of JavaScript.

- **Linting and Formatting:**
    - **ESLint:** Use ESLint to enforce code style and prevent errors.
    - **Prettier:** Use Prettier to automatically format the code.

- **Deployment Best Practices:**
    - **Environment Variables:** Use environment variables to configure the application for different environments.
    - **CDN:** Use a CDN to serve static assets.

- **CI/CD Integration:**
    - **Automated Testing:** Run tests automatically as part of the CI/CD pipeline.
    - **Automated Deployment:** Deploy the application automatically to different environments.

This comprehensive guide should help you build robust, maintainable, and performant Redux applications. Remember to stay up-to-date with the latest best practices and tools in the Redux ecosystem.
1. Code Organization and Structure: