Tutorial: Building ExpenseApp with React Native and Expo Chapter 1: Web, HTML, CSS & JavaScript Fundamentals Chapter 2: Orientation & Environment Setup Chapter 3: JSX & Core Components Chapter 4: State, Props & Component Architecture Chapter 5: Lists & Layout with Flexbox Chapter 6: Inputs & Form Handling Chapter 7: React Native Tutorial – StickerSmash with Expo Chapter 8: Advanced JavaScript for React Native Chapter 9: Form Handling & Validation with Formik and Yup Chapter 10: Navigation with Expo Router Chapter 11: Navigation Params & Modals Chapter 12: React Hooks, Side Effects & Data Flow Chapter 13: Global State Management with Context API & AsyncStorage Chapter 14: API Integration, Async Operations & Error Handling Chapter 15: Dynamic Bottom Tabs & Drawer Navigation Chapter 16: Advanced JavaScript – Async Patterns Chapter 17: Device APIs – Camera, Image Picker & Location Chapter 18: Notifications & Permissions Chapter 19: Animations & Microinteractions Chapter 20: Performance Optimization Chapter 21: TypeScript Fundamentals for React Native Chapter 22: Theme Context & Dark Mode Chapter 23: Advanced TypeScript – Navigation Types & API Typings Chapter 24: Expo Router Authentication & Transaction Module Chapter 25: Testing Fundamentals (Jest & React Native Testing Library) Chapter 26: Debugging & Troubleshooting Chapter 27: Code Quality & Refactoring Chapter 28: Build & Deployment with Expo (EAS) Chapter 29: Capstone Build-out – Features, Polish & Production Readiness Chapter 30: Capstone Demo, Final Review & Next Steps

Chapter 27: Code Quality & Refactoring


In previous chapters, we built several ExpenseApp features using:

  • Navigation
  • Context API
  • AsyncStorage
  • APIs
  • Forms & Validation
  • Expo Router
  • TypeScript
  • Testing
  • Debugging

As applications grow larger, maintaining clean and scalable code becomes extremely important.

Without proper code quality practices:

❌ Components become too large

❌ Logic gets duplicated

❌ Bugs increase

❌ Debugging becomes difficult

❌ New developers struggle to understand the codebase

Modern React Native applications solve these problems using:

✅ Consistent coding standards

✅ Refactoring techniques

✅ Reusable architecture

✅ Linting and formatting tools

In this chapter, we will improve the quality, readability, and maintainability of ExpenseApp.


🎯 What You Will Learn

By the end of this chapter, you will:

  • Understand why code quality matters
  • Configure ESLint and Prettier
  • Apply coding standards
  • Organize scalable folder structures
  • Extract reusable hooks and utilities
  • Follow naming conventions
  • Reduce code duplication
  • Refactor React Native components safely

⚡ Why Code Quality Matters

Good code quality improves:

✅ Readability

✅ Maintainability

✅ Scalability

✅ Team collaboration

✅ Debugging


🔹 Without Good Code Quality

Applications often suffer from:

❌ Inconsistent styles

❌ Repeated logic

❌ Large components

❌ Difficult onboarding

❌ Increased bugs


🔹 With Good Code Quality

Applications become:

✅ Cleaner

✅ Easier to extend

✅ Easier to debug

✅ Easier to test


🔹 Real ExpenseApp Example

Imagine:

  • 20+ screens
  • Multiple developers
  • APIs
  • Theme support
  • Authentication
  • Transactions
  • Analytics

Without proper structure, the project quickly becomes difficult to manage.


🧹 ESLint Setup


🔹 What is ESLint?

ESLint identifies:

✅ Code issues

✅ Bad practices

✅ Style inconsistencies


🔹 Why Important?

ESLint helps prevent:

❌ Unused variables

❌ Incorrect hooks usage

❌ Accidental mistakes


🔹 Install ESLint

npm install --save-dev eslint

🔹 Initialize ESLint

npx eslint --init

🔹 Basic ESLint Configuration

📁 .eslintrc.json

{
    "extends": ["eslint:recommended", "plugin:react/recommended"]
}

🔹 ESLint Benefits

Benefits:

✅ Detects errors early

✅ Improves consistency

✅ Encourages best practices


🔹 Example Warning

const data = 10;

Unused variable warning helps clean unnecessary code.


🎨 Prettier Setup


🔹 What is Prettier?

Prettier automatically formats code consistently.


🔹 Why Useful?

Instead of manually formatting:

❌ Indentation

❌ Quotes

❌ Line spacing

Prettier formats automatically.


🔹 Install Prettier

npm install --save-dev prettier

🔹 Prettier Configuration

📁 .prettierrc

{
    "semi": true,
    "singleQuote": true,
    "trailingComma": "all"
}

🔹 Benefits

✅ Consistent formatting

✅ Better readability

✅ Saves development time


🔹 ESLint + Prettier Together

Use both together:

Tool Purpose
ESLint Code quality
Prettier Code formatting

📁 Scalable Folder Structure

As applications grow, proper structure becomes essential.


🔹 Recommended ExpenseApp Structure

src
│
├── app
├── components
├── hooks
├── services
├── contexts
├── utils
├── constants
├── types
├── styles

🔹 Why This Structure Works

Benefits:

✅ Better organization

✅ Easier navigation

✅ Better scalability

✅ Cleaner architecture


🔹 Folder Responsibilities

Folder Purpose
app Screens & routes
components Reusable UI
hooks Reusable logic
services APIs
utils Helper functions
contexts Global state

🪝 Extracting Reusable Hooks

Hooks help separate logic from UI.


🔹 Problem Before Refactoring

useEffect(() => {
    fetchTransactions();
}, []);

This logic may repeat in multiple screens.


🔹 Better Approach

📁 src/hooks/use-transactions.ts

import { useEffect, useState } from "react";

export default function useTransactions() {
    const [transactions, setTransactions] = useState([]);

    useEffect(() => {
        loadTransactions();
    }, []);

    const loadTransactions = async () => {
        // Fetch data
    };

    return {
        transactions,
    };
}

🔹 Benefits of Custom Hooks

✅ Reusable logic

✅ Cleaner components

✅ Easier testing

✅ Better maintainability


🔹 Cleaner Screen Example

const { transactions } = useTransactions();

Much cleaner than repeating API logic everywhere.


🧩 Extracting Utilities

Utilities contain reusable helper functions.


🔹 What Should Go Into utils?

Examples:

✅ Formatting

✅ Calculations

✅ Date helpers

✅ Validation helpers


🔹 Example Utility

📁 src/utils/calculate-total.ts

export const calculateTotal = (transactions) => {
    return transactions.reduce((sum, item) => sum + item.amount, 0);
};

🔹 ExpenseApp Usage

const total = calculateTotal(transactions);

🔹 Why Utilities Matter

Benefits:

✅ Reusable logic

✅ Reduced duplication

✅ Easier maintenance


🔤 Naming Conventions

Consistent naming improves readability significantly.


🔹 Recommended Naming Rules

Item Convention
Components PascalCase
Functions camelCase
Hooks useSomething
Constants UPPER_CASE
Files Consistent naming

🔹 Examples

const calculateTotal = () => {};

const MAX_LIMIT = 1000;

🔹 ExpenseApp Examples

✅ TransactionItem.tsx

✅ useTransactions.ts

✅ calculate-total.ts


🔁 Reducing Code Duplication

Repeated code increases maintenance difficulty.


🔹 Problem Example

<Text>{item.title}</Text>

<Text>{item.amount}</Text>

Repeated across multiple screens.


🔹 Better Approach

Create reusable component.

📁 src/components/transaction-item.tsx

type Props = {
    title: string;
    amount: number;
};

export default function TransactionItem({ title, amount }: Props) {
    return (
        <Text>
            {title}: ₹{amount}
        </Text>
    );
}

🔹 DRY Principle

DRY means:

Don't Repeat Yourself

🔹 Benefits

✅ Less duplication

✅ Easier updates

✅ Cleaner architecture


🧪 ExpenseApp Refactoring Example


🔹 Before Refactoring

❌ API logic inside screen

❌ Repeated calculations

❌ Repeated form logic

❌ Large components


🔹 After Refactoring

✅ APIs moved to services

✅ Hooks extracted

✅ Utilities reused

✅ Components simplified


🔹 Result

Application becomes:

✅ Cleaner

✅ Easier to test

✅ Easier to scale


⚡ Refactoring Strategies

Refactoring should be gradual and safe.


🔹 Small Steps

✅ Refactor incrementally

❌ Avoid rewriting everything together


🔹 Keep Application Working

After every refactor:

✅ Test functionality

✅ Verify UI

✅ Run application


🔹 Improve Readability

Examples:

✅ Better variable names ✅ Smaller functions ✅ Smaller components


🔹 Extract Reusable Logic

Move reusable logic into:

✅ hooks ✅ utils ✅ services


🔹 Keep Components Focused

Large components are difficult to maintain.

Prefer:

✅ Smaller reusable components


⚠️ Common Mistakes

❌ Over-refactoring ❌ Breaking working code ❌ Ignoring naming conventions ❌ Large monolithic components ❌ Keeping duplicated logic


✅ Best Practices

✅ Use ESLint + Prettier ✅ Keep folder structure organized ✅ Extract reusable hooks ✅ Extract utilities ✅ Follow naming conventions ✅ Apply DRY principle ✅ Refactor regularly


🧪 Practice Exercises

  1. Extract transaction API into service
  2. Create reusable TransactionItem component
  3. Create useTransactions hook
  4. Move calculations into utils
  5. Add ESLint configuration
  6. Add Prettier configuration
  7. Refactor large screen into smaller components

📘 Chapter Summary

In this chapter, you:

✅ Improved code quality practices ✅ Configured ESLint and Prettier ✅ Organized scalable folder structure ✅ Extracted reusable hooks and utilities ✅ Applied naming conventions ✅ Reduced code duplication ✅ Learned safe refactoring strategies ✅ Improved ExpenseApp maintainability

Need help with your project?
I can help you explore our services or start an inquiry.