π― Introduction
When working on a React project, organizing your files and folders effectively is crucial for scalability, maintainability, and team collaboration. A well-structured project helps developers navigate the codebase efficiently, reduces complexity, and promotes best practices. ποΈ
In this article, we will explore a scalable folder structure for React applications using TypeScript, styled-components, Redux, and Context API, considering modularisation, separation of concerns, and best coding practices. π
π Basic Folder Structure
A modern React project using TypeScript, styled-components, Redux, and Context API follows this structure:
my-app/
βββ node_modules/
βββ public/
βββ src/
β βββ App.tsx
β βββ index.tsx
β βββ components/
β βββ assets/
β βββ styles/
β βββ services/
β βββ hooks/
β βββ context/
β βββ pages/
β βββ utils/
β βββ routes/
β βββ store/
β β βββ slices/
β β βββ store.ts
β βββ config/
β βββ theme/
β βββ tests/
βββ .gitignore
βββ package.json
βββ tsconfig.json
βββ README.md
π¦ Detailed Folder Structure and Best Practices
π 1. Store β Redux State Management
This folder contains Redux store configuration and slices for state management.
store/
βββ slices/
β βββ authSlice.ts
β βββ userSlice.ts
β βββ themeSlice.ts
βββ store.ts
Example Redux Slice:
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface ThemeState {
mode: "light" | "dark";
}
const initialState: ThemeState = {
mode: "light",
};
const themeSlice = createSlice({
name: "theme",
initialState,
reducers: {
toggleTheme: (state) => {
state.mode = state.mode === "light" ? "dark" : "light";
},
},
});
export const { toggleTheme } = themeSlice.actions;
export default themeSlice.reducer;
π 2. Context β Context API for Global State
Stores context providers for managing app-wide state without prop drilling.
context/
βββ AuthContext.tsx
βββ ThemeContext.tsx
βββ SidebarContext.tsx
Example Sidebar Context API:
import React, { createContext, useState, ReactNode, useContext } from 'react';
type SidebarContextType = {
isOpen: boolean;
toggleSidebar: () => void;
};
const SidebarContext = createContext<SidebarContextType | undefined>(undefined);
export const SidebarProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const toggleSidebar = () => setIsOpen(!isOpen);
return (
<SidebarContext.Provider value={{ isOpen, toggleSidebar }}>
{children}
</SidebarContext.Provider>
);
};
export const useSidebar = () => {
const context = useContext(SidebarContext);
if (!context) throw new Error('useSidebar must be used within a SidebarProvider');
return context;
};
π 3. Theme β Global Theme & Styled-Components
Stores the global theme configuration and styled-components for consistent UI styling.
Theme Configuration:
export const theme = {
colors: {
primary: "#007bff",
secondary: "#6c757d",
backgroundLight: "#ffffff",
backgroundDark: "#121212",
},
spacing: {
small: "8px",
medium: "16px",
large: "24px",
},
};
Example Styled Component:
import styled from "styled-components";
export const Button = styled.button`
background-color: ${(props) => props.theme.colors.primary};
color: white;
padding: ${(props) => props.theme.spacing.medium};
border-radius: 5px;
cursor: pointer;
`;
π οΈ 4. Hooks β Custom Hooks for Reusability
- A place for storing reusable custom hooks.
- Keeps logic modular and reusable.
hooks/
βββ useFetch.ts
βββ useDebounce.ts
βββ useTheme.ts
Example Custom Hook:
import { useState, useEffect } from "react";
export function useDebounce(value: string, delay: number = 500) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(handler);
}, [value, delay]);
return debouncedValue;
}
π§ͺ 5. Testing Best Practices
- Stores unit tests and integration tests.
- Uses Jest and React Testing Library.
tests/
βββ components/
β βββ Button.test.tsx
βββ hooks/
β βββ useDebounce.test.ts
Example Test Case:
import { render, screen } from "@testing-library/react";
import { Button } from "../../src/components/Button";
test("renders button correctly", () => {
render(<Button>Click Me</Button>);
expect(screen.getByText(/click me/i)).toBeInTheDocument();
});
β Conclusion
A scalable React project using TypeScript, styled-components, Redux, and Context API ensures:
- πΉ Type safety with TypeScript.
- πΉ Modular styling with styled-components.
- πΉ Separation of concerns through hooks, services, and context.
- πΉ Efficient state management via Redux Toolkit & Context API.
- πΉ Reusability & Scalability with custom hooks & optimized folder structure.
π€ How do you structure your React projects? Letβs discuss in the comments! π
Top comments (0)