React + TypeScript app built using clean architecture principles.

Last update: Jun 26, 2022

Frontend Clean Architecture

Read this in Russian 🇷🇺

An example app built using the clean architecture.

Things to Consider

There are a few compromises and simplifications in the code that are worth to be mentioned.

Shared Kernel

Shared Kernel is the code and data on which any modules can depend, but only if this dependency would not increase coupling. More details about the limitations and application are well described in the article "DDD, Hexagonal, Onion, Clean, CQRS, ... How I put it all together".

In this application, the shared kernel includes global type annotations that can be accessed anywhere in the app and by any module. Such types are collected in shared-kernel.d.ts.

Dependency in the Domain

The createOrder function uses the library-like function currentDatetime to specify the order creation date. This is not quite correct, because the domain should not depend on anything.

Ideally, the implementation of the Order type should accept all the necessary data, including the date, from outside. The creation of this entity would be in the application layer in orderProducts:

async function orderProducts(user: User, { products }: Cart) {
  const datetime = currentDatetime();
  const order = new Order(user, products, datetime);

  // ...
}

Use Case Testability

The order creation function orderProduct itself is framework-independent right now and can't be used and tested in isolation from React. The hook wrapper though is only used to provide the use case to components and to inject services into the use case itself.

In a canonical implementation, the function of the use case would be extracted outside the hook, and the services would be passed to the use case via a last argument or a DI:

type Dependencies = {
  notifier?: NotificationService;
  payment?: PaymentService;
  orderStorage?: OrderStorageService;
};

async function orderProducts(
  user: User,
  cart: Cart,
  dependencies: Dependencies = defaultDependencies
) {
  const { notifier, payment, orderStorage } = dependencies;

  // ...
}

Hook would then become an adapter:

function useOrderProducts() {
  const notifier = useNotifier();
  const payment = usePayment();
  const orderStorage = useOrdersStorage();

  return (user: User, cart: Cart) =>
    orderProducts(user, cart, {
      notifier,
      payment,
      orderStorage,
    });
}

In the sources, I thought it was unnecessary, as it would distract from the essence.

Crooked DI

In the application layer we inject services by hand:

export function useAuthenticate() {
  const storage: UserStorageService = useUserStorage();
  const auth: AuthenticationService = useAuth();

  // ...
}

In a good way, this should be automated and done through the dependency injection. But in the case of React and hooks, we can use them as a “container” that returns an implementation of the specified interface.

In this particular application, it didn't make much sense to set up the DI because it would distract from the main topic.

GitHub

https://github.com/bespoyasov/frontend-clean-architecture
You might also like...

A system combining classical traces dumping tools and a ReactJS web app for live 3D graph rendering of streamed graph data derived from traces

A system combining classical traces dumping tools and a ReactJS web app for live 3D graph rendering of streamed graph data derived from traces

The DynaGraph framework: a system combining classical traces dumping tools (i.e. the tshark tool and Firefox's Network Monitor component) and a ReactJS web app for live 3D graph rendering of streamed graph data derived from traces

Apr 28, 2022

A frontend Framework for building B2B applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design

A frontend Framework for building B2B applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Material Design

react-admin A frontend Framework for building data-driven applications running in the browser on top of REST/GraphQL APIs, using ES6, React and Materi

Jun 26, 2022

Create beautfiful custom applications using 100ms' React SDK.

Create beautfiful custom applications using 100ms' React SDK.

Create beautfiful custom applications using 100ms' React SDK.

Jun 17, 2022

Use React in Vue3 and Vue3 in React, And as perfect as possible

Use React in Vue3 and Vue3 in React, And as perfect as possible

Veaury (pronounced /ˈvjuːri/, inspired by 'beauty') is a tool library. It is built on the Vue and React framework. It's use cases include using both Vue and React in one app, migrating from React to Vue or from Vue to React

Jun 20, 2022

The React Framework

Next.js Getting Started Visit https://nextjs.org/learn to get started with Next.js. Documentation Visit https://nextjs.org/docs to view the full docum

Jun 19, 2022

Build blazing fast, modern apps and websites with React

Gatsby v2 ⚛️ 📄 🚀 Fast in every way that matters Gatsby is a free and open source framework based on React that helps developers build blazing fast w

Jun 19, 2022

The Full-stack Framework for React and other in Deno.

The Full-stack Framework for React and other in Deno.

Jun 17, 2022

A most advanced ssr framework support React/Vue2/Vue3 on Earth that implemented serverless-side render specification.

A most advanced ssr framework support React/Vue2/Vue3 on Earth that implemented serverless-side render specification.

A most advanced ssr framework support React/Vue2/Vue3 on Earth that implemented serverless-side render specification.

Jun 18, 2022

web3-react🧰 A simple, maximally extensible, dependency minimized framework for building modern Ethereum dApps

🧰 A simple, maximally extensible, dependency minimized framework for building modern Ethereum dApps

Jun 24, 2022
Comments
  • 1. React Query implementation

    Hello Alex, first off I would like to thank you for the detailed article and for sharing this with the community, I've played a bit with this architecture and now I want to implement it in a real world project, which is why I'm raising this issue, since I'm planning to use React Query as my server state management library and I can't figure out how or rather couldn't settle on a solution...

    Since react query already handles state management and async calls I feel like it has two types of adapters in one (storage service and api service), i saw how you suggested to implement redux toolkit in one of the previous issues, but this one is different since i don't see how we can decouple react-query from the business logic here... unless we use the library directly with the UI layer (react) ? since it's a react specific library anyways unlike redux, but it must interact with the Application layer ofc for the reasons sepcified earlier... this where i'm being stuck now, since if there is a way to implement React query with the Clean Architecture, I think it would be a very solid combination.

    Only potential solution I have now is to wrap each react query function (useQuery, useMutation etc...) in a hook and use it as an adapter somehow that implements a service and then use that in the application layer...

    Thank you in advance.

    Reviewed by BendrissM at 2022-05-27 12:25
  • 2. Scaling this to the practical level - replacing store with big external state management library.

    Hello, I see that implementation of storage is realized in useContext. Which is fine, that is just an implementation and nothing more.

    But I am concerned that bringing some big external library like redux-toolkit would actually change architecture of your code a little bit, by changing your domain interfaces for storage.

    How ? Well redux brings actions, reducers, dispatching, and middlewares for async communication. And currently I can't see how can you completely separate all of this from your domain logic, and hide it behind your interfaces.

    Also even if you manage to do it somehow ( like I did somehow.. somehow I mean it changed my domain interfaces but I managed to hide it again) it is still going to be against what is redux-toolkit paradigm, and you will end up with single reducer that sets whole slice.. I am not sure if that's okay?

    Here is what I managed to do and all my concerns in one place : https://stackoverflow.com/questions/71649550/clean-architecture-react

    I hope you will find the time to answer this. Thanks for your time.

    Reviewed by WingsDevelopment at 2022-03-29 11:46
  • 3. Improve mobile user experience and fix minor visual errors

    This PR improves the user experience for mobile users. The grid layout is now responsive. That means mobile users no longer have to scroll horizontally to see all cookies. Futhermore the name of the logged in user now breaks into the next line if there is not enough space to fit the title and the name in the header.

    Apart from that I fixed some minor visual errors. By adding some padding to the cookie image the cookie no longer overlaps the text for the toppings. I added some spacing on the "In your cart"-text so it no longer sticks to the "add to cart"-button.

    Reviewed by Async10 at 2021-10-05 15:09
  • 4. Modify: replace useStore hook with adapter

    In the cookie UI, I found that the store was accessed directly using the useStore rather than through the adapter.

    I thought it was right to approach using each adapter rather than directly from an architectural point of view, so I modified it in the direction of approaching using an adapter.

    I was very impressed by the article and this repository, and I sincerely thank you for your help.

    Reviewed by younuk23 at 2022-01-07 06:39
🛡️ ⚛️ A simple, scalable, and powerful architecture for building production ready React applications.

??️ ⚛️ A simple, scalable, and powerful architecture for building production ready React applications.

Jun 21, 2022
On layered architecture
On layered architecture

On layered architecture

Jun 16, 2022
Create a SPA project using Mithril JS framework and design layout by JSX syntax and use Typescript and Vite for build system.
Create a SPA project using Mithril JS framework and design layout by JSX syntax and use Typescript and Vite for build system.

Mithril TS(Type script) JSX Create a SPA project using Mithril JS framework and design layout by JSX syntax and use Typescript and Vite for build syst

Feb 22, 2022
Web App using react framework

waldo.vision This is the website for waldo-anticheat :D Libraries used: React React-router React-router-hash-link React-helmet TODO: improve this list

Nov 12, 2021
React tic-tac-toe example implemented in TypeScript

React Tutorial TS implementation What React's official Tic Tac Toe tutorial in TypeScript fashion. DIY step npm install npm start to start dev server

May 16, 2022
⚡️The Fullstack React Framework — built on Next.js
⚡️The Fullstack React Framework — built on Next.js

⚡️The Fullstack React Framework — built on Next.js

Jun 16, 2022
⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails
⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

Oct 12, 2021
Ethylene - a React library that is built for supporting Web3 front-end developers
Ethylene - a React library that is built for supporting Web3 front-end developers

Ethylene Javascript React hooks, utils, and UI components for interacting with Ethereum Smart Contracts Introduction Ethylene is a React library that

Jun 21, 2022
A utility-first CSS-in-JS framework built for React 💅👩‍🎤⚡️
A utility-first CSS-in-JS framework built for React 💅👩‍🎤⚡️

A utility-first CSS-in-JS framework built for React. npm install @xstyled/styled-components styled-components Docs See the documentation at xstyled.de

Jun 21, 2022
Datapod for React - a framework which extends create-react-app to enables you to quickly build data-driven sites
Datapod for React - a framework which extends create-react-app to enables you to quickly build data-driven sites

This is a framework which extends create-react-app to enables you to quickly build data-driven sites. This code is generated from the Datapod-for-React Core application.

Mar 19, 2022