DEV Community

Cover image for Architecting React Apps Like it's 2030

Architecting React Apps Like it's 2030

Renato Pozzi on July 18, 2022

There is one problem that every React Developer falls into during his journey. This is how to structure a good app architecture. This article will...
Collapse
 
mabouhha profile image
боженька-нерд

this is a good article, but not enough for large spa (more than 1000 react components) with rich business logic. Previously, I used this approach, and everything turned into a dump. I found the solution in the Feature Sliced Design architecture. I advise those who work on large SPAS to familiarize themselves. feature-sliced.design/en/docs/intro
For business card sites, FSD is overhead.

Collapse
 
itsrennyman profile image
Renato Pozzi

Thanks for the link you shared! I'm gonna have a look also at it!

Collapse
 
ekeijl profile image
Edwin

This looks really good. I tried it a bit today, but I get confused where to place custom hooks and context, I'm not sure if hooks translate really well to this architecture.

From the example repos I deduce that data fetching hooks go in the model segment, UI related hooks in the UI segment.

When using React.Context, I have a Provider at the top level, so that needs to go in the app layer, but the Context can be accessed by lower layers to read the Context so the React.createContext goes in the shared layer?

Collapse
 
mabouhha profile image
боженька-нерд

Yes, all right.
The model segment is your little piece of domain, an aggregate (in DDD terms). Data fetching 100% should be located here.

UI related hooks - yes, they can be put in the ui segment. But first I ask myself the question: "Will there ever be a component in the application in which I can reuse this hook? Is such a component located in another segment? How sure am I?"
If the hook will be used only in one ui segment, it remains in this place.
If I'm not sure, then I move it to the lib segment.
If the hook is 100% reused, then I transfer it to shared/lib.

React.context - also depends on the usage. If you use it in several slices, then /shared. If in one slice, then put it right here. But if there is a need to use multiple slices, it's worth thinking about: "Is it certain that this data cannot be encapsulated in a single entity? Or do I really need a complete set of this data in all places? Will I benefit if I encapsulate context data in multiple entities? Is there anything to gain from encapsulating the context?"

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

This post has my Quality Check! 😁

I'd just add a styles file along with a component, i.e.

├── components
   ├── common
      └── button
          ├── button.tsx
          ├── button.stories.tsx
          ├── button.spec.tsx
          ├── button.styles.js
          └── index.ts
Enter fullscreen mode Exit fullscreen mode

While using styled-components. You can use it along TS without issues of course, just import the cssprop in your project -> see the doc for further details.

This way we cover the issues related to a growing project in which classNames are generated indiscriminatedly. Also it provides inheritance (while other solutions like Tailwind does not) and provides a straight way to pass props to the styles for modifications.
i.e.

 const Button = styled.button`
    padding: 8px 12px;
    border: none;
    border-radius: 4px;
    background-color: ${(props) => (props.status === 'error' ? 'red' : 'green')};
  `;

<Button status='error'>{message}</Button>
<Button status='ok'>{message}</Button>
Enter fullscreen mode Exit fullscreen mode

This way we let the design logic inside the styles where it belongs :)

Best regards!

Collapse
 
itsrennyman profile image
Renato Pozzi

Thanks for the tip! Yeah this is definitely a good addition to this architecture for styled-components/emotion users.

Collapse
 
yogeshktm profile image
yogeshwaran

Great one.

Very useful for react starters like me. also i saw some of the projects used folder/concept like Container which have stateful logics of components inside it.

Is that container concept still a best practice ? and how you maintain states for components. since i am also used this container for few projects so got confused whether its still valid one

Thanks

Collapse
 
itsrennyman profile image
Renato Pozzi

The point is: that there is no best practice at all, but there are good and bad solutions to specific problems. I use container patterns a lot. Because it keeps my function components easy to maintain avoiding side effects inside of them.

Collapse
 
yogeshktm profile image
yogeshwaran

Thanks for the reply :)

Thread Thread
 
itsrennyman profile image
Renato Pozzi

You're welcome!

Collapse
 
wkrueger profile image
wkrueger

in 2030 nobody will be using this mess of a framework

Collapse
 
luigidv profile image
Luigi Davila • Edited

I think React LIBRARY is good enough when you know how to explode and get the best from the bundle. Sometimes the mess is in our side.

For an ordered and visible component hierarchy when talking about Views, Interfaces, etc … I recommend you to go for NextJS Framework.

Collapse
 
localpath profile image
Garrick Crouch

Good job. You may want to use a services directory for anything that interacts with the outside world such as http/wss clients. Hooks are a great way to encapsulate using those clients ie swr/react query

Collapse
 
itsrennyman profile image
Renato Pozzi

Yeah, that's another good point. Thanks for sharing this!

Collapse
 
aishanipach profile image
Aishanii

Love how simple yet effective this is. React is perfect for people who love organised code. For the repetitive API call, I think redux store can be used and a redux folder with procedure based sub folders, namely actions, store and container, would work better.

Would love to see more project specific techniques! :D

Collapse
 
itsrennyman profile image
Renato Pozzi

Thanks for the comment! :)

Collapse
 
roccoluke profile image
Luke Rocco

Good advice 👏 Been using this architecture for a while though. In terms of directories, when dealing with large enterprise apps, components folder is usually subdivided more grnaaularly, such as using atomic design method. Same goes for hooks/store/context, get subdivided by feature.

Collapse
 
itsrennyman profile image
Renato Pozzi

Good point, yeah i think is definitely affordable for bigger applications.

Collapse
 
jackmellis profile image
Jack

As someone who spends 90% of their time in business logic, just throwing api in as an afterthought is a sad but very common move (although still significantly better than just stuffing api calls into your components).

I always ensure any medium-large scale application has something like onion/hexagonal architecture, where business logic has a defined home, api calls are abstracted into tech-agnostic functions, and there is a distinct divide between presentation and operations.

My ui layer does look a lot like this, but it really should just be one part of the application heirarchy, not the entire focus of it.

Collapse
 
madza profile image
Madza

This was a good read 👍✨💯

Collapse
 
itsrennyman profile image
Renato Pozzi

Thank you so much!

Collapse
 
madza profile image
Madza

My pleasure 👍✨💯

Collapse
 
raibtoffoletto profile image
Raí B. Toffoletto

Great Article! 🎉 I agree with most of it (a part of kebab-case.... 😶) and usually follow this structure. Folks can organize stuff differently, but the most important is to be consistent!! So anyone new can find themselves after a bit of investigation. 😁

Collapse
 
itsrennyman profile image
Renato Pozzi

I totally understand you, i used to hate kebab-case.. but after a while of forcing me keeping it, i'm starting to love it.

Collapse
 
callmehomer profile image
Kamil Homernik

Did I get it right? When you have index.ts in you button folder you don't need to import it by writing '... from 'components/button/button'' and just 'components/button' will work?

Collapse
 
itsrennyman profile image
Renato Pozzi

Yes! :)

Collapse
 
blitz_cloud profile image
Ionut aka BlitzCloud

Nice article. Thx, I am new to React but i could go through witout any issues. It definitely gave me a good direction. 😀Coding

Collapse
 
itsrennyman profile image
Renato Pozzi

You're welcome!

Collapse
 
andrewbaisden profile image
Andrew Baisden

Interesting way to look at it. There are countless ways to solve this problem and these were really good.

Collapse
 
kwirke profile image
Kwirke

Good article about folder organization. However, "architecture" is a much broader subject that involves data and state management, abstractions and interfaces used, extensibility, bug traceability, documentation, client-server communication, and client bundling and serving, among others. So there's a bit of a clickbait there.

Collapse
 
dalsoft profile image
DalSoft • Edited

Enjoyed the post I had similar thoughts a while back and come up with something similar:
app1/
├─ src/
│ ├─ Components/
│ ├─ Apis/
│ ├─ Assets/
│ ├─ Components/
│ ├─ Context/
│ ├─ Hooks/
│ ├─ Pages/
│ ├─ Styles/
│ ├─ Utils/

I turned it into a GitHub template main thing for me is exactly what you said everything related to the component styles, tests etc should live in the same folder. I've kept to this with very large apps, and it works really well as your app grows.

Collapse
 
pbergwerff profile image
pbergwerff

For sake of scalability I would split up your components by using Atom Design Pattern.

atomicdesign.bradfrost.com/chapter-2/

Collapse
 
joelbonetr profile image
JoelBonetR 🥇

In my experience that never ends well IRL 😆 It has the same issues than CSS classNames. When people can't find the 'desired' atom they create a new one with a different name (language is sometimes a barrier isn't it?)

Collapse
 
itsrennyman profile image
Renato Pozzi

I personally experienced the same.

Collapse
 
brngranado profile image
Bryan Granado

How did a services folders ? or only is an example for files ?

Collapse
 
talweltsch profile image
Tal Weltsch

Hey! good read!
Messaged you on twitter!

Collapse
 
cdcwatson profile image
Craig

Any interesting edge cases to consider?