|
| 1 | +# React Clean Architecture Example |
| 2 | + |
| 3 | +This project demonstrates a **Clean Architecture** implementation in React, adhering to the **SOLID** principles. It serves as a reference for structuring a React application with a focus on maintainability, scalability, and separation of concerns. |
| 4 | + |
| 5 | +The application is a simple task list, allowing users to add tasks and view them. This example emphasizes modularity and clear separation of concerns, making it easy to adapt to more complex projects. |
| 6 | + |
| 7 | +## Features |
| 8 | + |
| 9 | +- Add a new task |
| 10 | +- Display the list of tasks |
| 11 | + |
| 12 | +### Task Model |
| 13 | + |
| 14 | +The `Task` class is structured as follows: |
| 15 | + |
| 16 | +```ts |
| 17 | +export class Task { |
| 18 | + constructor( |
| 19 | + public id: number, |
| 20 | + public name: string, |
| 21 | + public completed: boolean = false |
| 22 | + ) {} |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +## Project Structure |
| 27 | + |
| 28 | +The project follows a modular structure based on the Clean Architecture pattern. Below is an overview of the main folders: |
| 29 | + |
| 30 | +``` |
| 31 | +src/ |
| 32 | +├── modules/ |
| 33 | +│ ├── task/ |
| 34 | +│ │ ├── useCases/ |
| 35 | +│ │ │ ├── createTaskUseCase.ts |
| 36 | +│ │ │ ├── deleteTaskUseCase.ts |
| 37 | +│ │ │ ├── getTasksUseCase.ts |
| 38 | +│ │ │ ├── refreshTasksAfterCreationUseCase.ts |
| 39 | +│ │ ├── di/ |
| 40 | +│ │ │ └── ioc.ts |
| 41 | +│ │ ├── domain/ |
| 42 | +│ │ │ ├── model/ |
| 43 | +│ │ │ │ └── Task.ts |
| 44 | +│ │ │ └── repository/ |
| 45 | +│ │ │ └── ITaskRepository.ts |
| 46 | +│ │ ├── infrastructure/ |
| 47 | +│ │ │ ├── dataSources/ |
| 48 | +│ │ │ │ └── MockDataSource.ts |
| 49 | +│ │ │ └── repositories/ |
| 50 | +│ │ │ └── taskRepository.ts |
| 51 | +│ │ ├── presenter/ |
| 52 | +│ │ │ ├── components/ |
| 53 | +│ │ │ │ └── TaskForm.tsx |
| 54 | +│ │ │ │ └── TaskList.tsx |
| 55 | +│ │ │ ├── pages/ |
| 56 | +│ │ │ │ └── TaskPage.tsx |
| 57 | +│ │ │ └── viewModels/ |
| 58 | +│ │ │ └── taskListViewModel.ts |
| 59 | +│ ├── user/ (empty for now, but set up as an example) |
| 60 | +├── components/ |
| 61 | +│ ├── ui/ |
| 62 | +│ │ ├── Button.tsx (empty for now, but set up as an example) |
| 63 | +│ ├── layout/ |
| 64 | +│ │ ├── Header.tsx (empty for now, but set up as an example) |
| 65 | +│ ├── common/ |
| 66 | +│ │ └── Spinner.tsx (empty for now, but set up as an example) |
| 67 | +├── shared/ |
| 68 | +│ ├── utils/ |
| 69 | +│ │ └── dateUtils.ts (empty for now, but set up as an example) |
| 70 | +│ └── types/ |
| 71 | +│ └── globalTypes.ts (empty for now, but set up as an example) |
| 72 | +└── App.tsx |
| 73 | +└── index.css |
| 74 | +└── main.tsx |
| 75 | +``` |
| 76 | + |
| 77 | +## Dependency Injection (IoC) |
| 78 | + |
| 79 | +The `ioc.ts` file is used to register dependencies using **Awilix** for Dependency Injection. Here's the configuration for the container: |
| 80 | + |
| 81 | +```ts |
| 82 | +const container = createContainer(); |
| 83 | + |
| 84 | +container.register({ |
| 85 | + // Data source |
| 86 | + dataSource: asClass(MockDataSource).singleton(), |
| 87 | + |
| 88 | + // Repository |
| 89 | + taskRepository: asFunction(taskRepository), |
| 90 | + |
| 91 | + // Use case |
| 92 | + getTasksUseCase: asFunction(getTasksUseCase).singleton(), |
| 93 | + createTaskUseCase: asFunction(createTaskUseCase), |
| 94 | + refreshTasksAfterCreationUseCase: asFunction( |
| 95 | + refreshTasksAfterCreationUseCase |
| 96 | + ), |
| 97 | + |
| 98 | + // ViewModel |
| 99 | + tasksViewModel: asFunction(tasksViewModel), |
| 100 | +}); |
| 101 | + |
| 102 | +export default container; |
| 103 | +``` |
| 104 | + |
| 105 | +## Installation |
| 106 | + |
| 107 | +1. Clone the repository: |
| 108 | + |
| 109 | + ```bash |
| 110 | + git clone https://github.com/Jszigeti/react-clean-architecture-example.git |
| 111 | + cd react-clean-architecture-example |
| 112 | + ``` |
| 113 | + |
| 114 | +2. Install dependencies: |
| 115 | + |
| 116 | + ```bash |
| 117 | + npm install |
| 118 | + ``` |
| 119 | + |
| 120 | +3. Run the development server: |
| 121 | + |
| 122 | + ```bash |
| 123 | + npm run dev |
| 124 | + ``` |
| 125 | + |
| 126 | +4. Open your browser and go to `http://localhost:3000`. |
| 127 | + |
| 128 | +## Technologies Used |
| 129 | + |
| 130 | +- React 18 |
| 131 | +- TypeScript |
| 132 | +- Awilix (for Dependency Injection) |
| 133 | +- Vite (for build and development) |
| 134 | +- ESLint (for linting) |
| 135 | + |
| 136 | +## Contributing |
| 137 | + |
| 138 | +Feel free to open an issue or submit a pull request to contribute improvements or features. |
| 139 | + |
| 140 | +## License |
| 141 | + |
| 142 | +This project is licensed under the MIT License. |
0 commit comments