DEV Community

Bad Habits of Mid-Level React Developers

Sam Magura on April 09, 2022

If you're a mid-level React developer looking to become an advanced React developer, this post is for you! I've been reviewing React code written ...
Collapse
 
tbm206 profile image
Taha Ben Masaud

While I agree with most of the advice given, some are subjective and opinionated and do not necessary reflect universally accepted best practices.

For example, I prefer SASS/LESS over css-in-js. But again, this is my own subjective preference. Similarly, I prefer to use Elm, ReScript or PureScript if I'm overly concerned with the correctness of the app. Otherwise, (JS + tests) is better than TS for fast development and less overhead of maintaining a mountain of TS types that often leak bugs anyways.

Also, it would be better to zoom out and think why React.memo helps. Perhaps restructuring the react tree would make several instances of React.memo redundant.

I know I'm in the minority but I hate hooks because of all the pitfalls one needs to remember when using them, especially when there are nested 2 or more levels deep. Check out RefractJs; no need for hooks. HoCs are better because they're a universal pattern; not a library's API.

Collapse
 
brense profile image
Rense Bakker

Css in js and typescript are best practices and every day more companies are joining the bandwagon asking for these skills. While I do personally also like to take a backseat in the bandwagon, css in js and typescript are quickly becoming industry standards (typescript already is) and you're going to hurt your career if you refuse to become proficient in these skills.

Collapse
 
tbm206 profile image
Taha Ben Masaud

Claiming css-in-js and TS are best practices is incorrect. However, claiming there's momentum behind these technologies is correct.

TS, in my opinion, is the new Java. It'll build a massive pile of horrible codebases that future developers will have to maintain. It's an opportunity as well as a curse 😅. Pure FP languages with clear FFI are better for guaranteeing the correctness of apps.

Thread Thread
 
brense profile image
Rense Bakker

I've worked extensively with existing codebases in both Java, Typescript and Javascript. Your claim that Typescript is the new Java is just a little bit ridiculous tbh... If you want to make such a crooked comparison, Typescript is more comparable to C# than Java. The pile of horrible codebases you talk about, I've seen them but they were all in Javascript.

Collapse
 
spock123 profile image
Lars Rye Jeppesen

css-in-js is horrible ,stop your self please.

Collapse
 
codewander profile image
Anon • Edited

Otherwise, (JS + tests) is better than TS for fast development and less overhead of maintaining a mountain of TS types that often leak bugs anyways.

I have been thinking this as well. I would only want to use rescript or elm, or just js. Of those three options, I am slightly leaning towards js with tests because I don't have to deal with any special tooling. If elm gains more momentum, or rescript launches a huge framework developed in rescript, I would make those my default. I am disappointed that Elm hasn't won (yet?). (I very rarely build small front ends, so my opinions here don't have a lot to back them up).

I have also been thinking about leaving business object data as json (e.g. package.elm-lang.org/packages/1602...) instead of converting to records, when using elm or rescript, because I think most business objects will eventually want some user defined fields.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

God damn! using TS as "good practice"... The post was good since I read such a stupid thing.

I encourage you to learn JS properly instead.
We've tools in JS to use as we need them, it's not the most used programming language around the world just by chance.

facts

Do you want type checking? Simply add

// @ts-check

at the top of your file, VSCode will handle it for you in dev time[*1], all you need to do is to add JSDoc to your functions/methods and variables, which is one of the most important best practices: Document your code.

Do you want types and function/method inference? Again, JSDoc.

Better intellisense? Guess what... JSDoc.

Do you want to produce a maintainable code? Apply SOLID and KISS patterns.

Since we're talking about react, you should know about prop-types as well, more useful than type-checking if you take in mind the context of React[*2].

About data fetching libraries, there's fetch API by default in JS, that can handle ALL existent features that HTTP requests provide (moreover fetch API is coming to Node as well). Why adding an additional one?

One important (and real) good practice is to add the minimum amount of third party libraries into your project. This makes your project more robust, faster to build/deploy and usually more secure.[*3]

personal opinion

I find styled-components useful and probably the best option for several reasons (everything is a component, no unused CSS, much cleaner than tailwind, sass/scss capabilities by default, JSX inside styles definition, it can handle JS props (usefull for interactions that CSS alone can't handle and you can place it on a different file).

I like to have 3 files in each component folder, those are, as example:

myComponent.js
myComponent.styles.js
myComponent.utils.js

Which I guess are self-explanatory (ask me if you want detail).


[*1] Meaning that you don't need to add TS to your project and waiting the extra build time, it will work, let's say, in runtime, while you are developing instead. 0 time wasted and same type-checking than adding the huge TS lib to your project, isn't it amazing? 🤗

[*2]Most part of the logic should be in the backend. You should only handle interaction logic in the frontend, which makes easier to scope everything where it belongs so you can swap your backend or frontend without the hell of a code with heavy coupling.
It may seem that React will exist forever but people that is migrating from JQuery-UI maybe thank the same back those days 😂

[*3] By robustness meaning that you don't need to update your project each time a lib changes it's way-to-work, relying on language API (if it suits the project needs) is so, usually better.
By secure I mean that the probability that a third party deals to a security hole is higher than using the language API itself as a general rule of thumb.
I find faster to build/deploy as self-explanatory.

Collapse
 
mehyam profile image
MehYam

Major error in your post: you centered your "personal opinion" header instead of aligning it to the top.

Collapse
 
srmagura profile image
Sam Magura

@mehyam 😂😂😂

Collapse
 
joelbonetr profile image
JoelBonetR 🥇

It's an introduction 😆

Collapse
 
haaxor1689 profile image
Maroš Beťko

Learning JS properly as you said and using Ts are by no means exclusive. You write to not use Ts but then immediately suggest to use ts-check pragma. While JSDoc is powerful tool, it shouldn't be used for typechecking your code, this again is thanks to TS extracting some info from your js documentation and by no means is a solid solution for larger projects.

Also about the data fetching libraries, you clearly didn't understood what they are for. React Query isn't there to replace fetch, it uses fetch to smartly and effectively work with async data.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited
Learning JS properly as you said and using Ts are by no means exclusive.

Sure it's not, I totally agree with this. I'm not editing the previous comment to keep things as they are, I should have been avoided the word "instead" at the end or communicate it on a different manner.

You write to not use Ts but then immediately suggest to use ts-check pragma.

I said that that if you want type-checking for any reason you can simply use this instead loading the entire TS as dependency in your project.

While JSDoc is powerful tool, it shouldn't be used for typechecking your code

¿Why not? JSDoc annotations live in comments, rather than directly in syntax, which I prefer but it's totally opinionated, you can choose one or another or none of both and it will be Ok if it suits your project needs.

this again is thanks to TS extracting some info from your js documentation and by no means is a solid solution for larger projects. Also about the data fetching libraries, you clearly didn't understood what they are for. React Query isn't there to replace fetch, it uses fetch to smartly and effectively work with async data.

This post is about good practices, so my comment is targeted to avoid opinionated stuff into good practices rather than discussing the usefulness of a given library.

We need to take apart what we "like" or what we found "useful" or what it worked "well for us in a specific use-case" so we can differentiate what are actual good practices than what are our preferences.

Do you prefer TS for some reasons? It's OK, go for it. Do you prefer to avoid using TS? It's equally good, go ahead. The same applies to fetching libraries.

Is strong typing things good? Sure it can avoid runtime errors, but it's not the only way to reach the same.

Saying that TS or fetching libraries are "good practices" is just so out of the reality that it simply can't fit. By all means, best practices are not language specific, just for that reason adding TS or a given lib is just an opinion (to which you can agree or not, but that's not the point of discussion).

Collapse
 
ekeijl profile image
Edwin

Great article, I agree with most of these points. Not too sure about using reducers for just arrays, since they also add a bit of complexity and boilerplate themself. I would say it helps if you can identify unique actions in your component tree that affect multiple parts of state.

One thing I noticed is that people try to come up with their own solutions while React has a somewhat opinionated solution for that problem. This mostly boils down to them trying to optimize prematurely or storing calculated values in state (leading to the problems you describe) - they think a rerender would be too expensive based on their gut feeling instead of actually measuring it.

I'm not a great fan of unit testing React related code (the internal state of your app), but for specific business logic it could make sense. I think Kent C. Dodds is on to something with his testing trophy - mostly write integration tests so you can verify the most important use cases of your app and try to avoid testing the internals.

Also, using testing library (with Cypress) was an eye-opener for me. Multiple times I tried writing a test using querying methods that test the interface based on what the user sees (aria role, form label, aria label, text, etc), but noticed I couldn't because there were no proper labels on my elements. By writing the test, the accessibility of my app improved as well! Win win!

Collapse
 
srmagura profile image
Sam Magura • Edited

Thanks Edwin. When I say "using reducers for arrays", I primarily am referring to the "I have an array of objects and the user can edit each object" use case. For a simple array of IDs, reducer is not really necessary.

I also love the testing trophy so I agree with you there!

@testing-library/cypress is an interesting topic... I have used React Testing Library and Cypress, just not together 😉

Collapse
 
brense profile image
Rense Bakker

I agree with everything, except the reducers. Although its good to stay up to date with a library like redux because of its widespread use, and using built in react hooks is definitely good advice. Personally I prefer more lightweight state management solutions like jotai and I hope to see a move away from redux in the industry.

Collapse
 
vital_tech_results profile image
Devadi Dev • Edited

This is a very professionally written article that benefits the dev.to community.

What are your thoughts on TailwindCSS? I've grown to prefer Tailwind over styled components.

I agree on the importance of Typescript. I recently worked on a large site with over a million dollars in monthly sales and it uses .js only (not a single .tsx file). In this regard, what differentiates an opinion from best practice. I think using TypeScript is best practice. Or is that an opinion?

I'm definitely sharing this on Linkedin.

Collapse
 
radulle profile image
Nikola Radulaški
  1. CSS modules yes, CSS-in-JS no. Using SCSS modules gives you same encapsulation you get with CSS-in-JS while offloading main thread. Sure, there's Lerna and similar libs that compile to CSS but they just add unnecessary complexity to the build system.
  2. If you use memoization too much something's wrong.
  3. Don't use state libs unless your app really needs them.
Collapse
 
decryptus007 profile image
Dominic

I've been using useState to handle most of my state in my React related project but I need to know more about how to handle state globally like using redux and the likes, can anyone recommend a good course for me to study?

Collapse
 
srmagura profile image
Sam Magura

The Redux Toolkit documentation has some good tutorials and guides for using Redux!

Collapse
 
joelbonetr profile image
JoelBonetR 🥇

Self documenting code is a lie that I honestly thank the community was aware of since long time ago.

Collapse
 
trickydisco profile image
Gavin

The other thing worth mentioning about reducers is to switch on state first than action (event). Most developers write them action first which means the event can be fired unconditionally. It even mentions this in the docs
redux.js.org/style-guide/style-gui...

Collapse
 
jorgemadson profile image
Jorge Madson

I loved this post, I am trying to improve my level as a react developer and I really liked the tips, I will read it every week until I internalized them.

Collapse
 
booboboston profile image
Bobo Brussels

Very helpful 🥳

Collapse
 
intermundos profile image
intermundos

And the last advice - you don't switch to Vue.

Collapse
 
getsetgopi profile image
GP

A new JavaScript expert is born :)

Collapse
 
paratron profile image
Christian Engel

Found the post mostly edgy but went along until the " Only use server rendering if you really need it ".

That has to be the worst tip ever :(