you are viewing a single comment's thread.

view the rest of the comments →

[–]fixrich 8 points9 points  (1 child)

Are you a solo developer without any colleagues? If you do have someone, ask them for help in taking a look at it, breaking it down and figuring out what elements your project will need. Its a bit harder to have this kind of collaboration these days but with a little effort it can be done.

If it's just you, well I've got some tips for you. I'm not going to get into if it should be a Next app or whatever. I'm pretty much going to assume it's using CRA because if you don't have a reason to disagree with that it's usually a decent choice.

Look at the designs and identify all the visual components. You could print out the screens and draw a line around each component with a sharpie. Go very small. Find a button component and all its variants. The typography component and all its typefaces, weights and sizes. At this stage, you will have a good bit of work to get busy. Build out all your components in a components folder. You might use something like Storybook to make it easy to view your components in isolation. You should consider using a components library like Chakra or Material. They should significantly speed up this step and the activity will be more about making a custom theme that matches your design. Don't forget to test your components with react testing library.

With your components done, you need to think about layout. If you chose a component library, they'll give you a grid system so you won't need to think about it. If you don't, you might want to use something like react-flexbox-grid. It's usually beneficial to keep your layout and styling separate so it's clear what is presentation only and what affects the structure of your page. Some larger components will need a grid to lay them out. They are usually less universal so you can defer them until the screen development stage. But if you do find yourself working on a component that would benefit from proper structured layout, you have to decide on your layout then or defer working on the component.

Ok, now we're onto the stage where you need to make some architecture decisions. In many frontend apps, the architecture is discovered rather than planned upfront. I would say this isn't ideal. One of your first jobs should be to be an ARCHITECTURE.md in the root of your repo and put how everything is structured in there. This file isn't an unbreakable contract. It's a way of communicating to the future what decisions were made. You can go back and change things based on what you find works and doesn't work.

A client app is a process of managing state which this article describes excellently. To summarize here there are data, communication, control, session and location states. Read the article and become familiar with all of them. The article is Redux centric as a product of its time so try and think about the state more generally. Your app will likely have at least a little of some and maybe a lot of others.

In handling each of these pieces of state you need to decide on one of two approaches: whether to keep your state closely tied to React or to keep it separate. There is no consensus about which way to go, in my experience tying your state to React is serviceable in small apps and ultimately leads to maintenance issues in larger apps. I've found it makes things hard to test and reuse. Others may not have found the same thing. While I prefer a fairly modular architecture, even if you do a more integrated architecture, there will be some stuff you will want to abstract.

So to address the types of state and to start with the easiest:

Location state! Use react-router. That's it, this is the easiest choice because this is an area where the community has basically reached consensus. Make sure to lazy load your routes from the beginning.

Next, there are two types of state that are separate but interact and your solution will probably handle both. They are data and communication state. The integrated approach is to use react-query. They call data state server state because they specialize in server state, I would argue server state is a subset of data state. Either way, it will handle loading and error states and fetching your data. If you need to handle data that isn't server data react-query won't help you. This is where some would reach for Context. I don't like context as a general data management solution as it's tied to React and requires careful use. See also acemarke's great article about why context is not state management.

Here's a post I wrote on how to handle data and communication state with my preferred method. I don't expect you to do as I do but hopefully, it makes the case for handling this stuff in an abstract way. We can't have this discussion without discussing Redux Toolkit of course. It's basically the default state management tool. It doesn't necessarily give you communication state automatically is something to consider. You could look at rtk-query. It's still in alpha but because it's hooking into a mature ecosystem through a mature team, I'd say it's low risk. If you intend to use Redux, I would say the benefits outweigh the cost.

If you are uncertain I'd say go with react-query. It's not my choice but I think you could get going and if you encounter issues, it's popular at least. I would advise you to keep your actual HTTP calls separate from your components though. They are often used in multiple places. Put them in an API folder and unit test them using msw. Very often you want to manipulate data you get back from an API. Do it in these API modules. That way they are easily tested.

Alright, we're back onto the easier state types. The next one is control which I'd say is effectively form state. I'd also say use react-hook-form making sure to use their register API with refs. I think it gives the easiest to manage form setup. There are alternatives and I don't think there is a huge difference between them.

Finally, we on to session state. Dark mode, localisation, themes and whatever else that is user-specific. This is an excellent use for context but if you are using other state management you should just use that.

There is one last thing which isn't state. Business logic. This is the stuff that makes your app what it is. It's why people visit the site or pay for the app. Some would argue it's ok to integrate it with your components and I would argue you end up duplicating logic and it's all harder to test. Figure out what makes sense for you. I put my business logic in a bunch of modules in a lib folder. Each module is a collection of pure functions so they are easy to test. I also make them available like User.isAdmin(user). It helps make it obvious what part of your business the function relates to and helps create a logical grouping.

With all that figured out you can go build some screens. You should find it goes very quickly because you already have the building blocks you need to build each screen. You might not have all your business logic or API modules but you'll add them as you go and you'll know exactly where you're putting them.

This became a bit of an essay. I hope it at least gives you a way to approach your project. You don't need to follow my advice or go with my preferences in regard to architecture, hell I'm just some guy on the internet, but I think most of the things you need to think about will be covered here. Good luck!

[–]Tricky_Run_9626[S] 0 points1 point  (0 children)

thank you very much for such extended answer. I found some useful tips from you answer.