What happens when you blindly follow the best practice without understanding why? You end up with software that is not optimized for your needs or environment.
This post explores some of the common best practices, why they don’t always work, and what’s a better approach.
Smart versus dumb components
The React community is especially fond of this pattern. The idea is to use “smart” components - which are responsible for handling data and business logic - and “dumb” components, which simply render UI based on input data.
While this pattern often works well, it can also lead to undesirable side effects, like prop drilling if you’re not careful. I’ve seen a project that introduced an insane amount of prop drilling because they wanted to prevent their “dumb” components from tapping into the global state.
With tools like GraphQL,
styled-components, Context API, and custom hooks, the boundaries between smart and dumb components become less relevant.
We can often combine these tools to create self-sufficient components that handle data processing AND render the UI. There’s no need to impose artificial separation.
I prefer treating this pattern as a suggestion rather than a strict rule.
Don’t Repeat Yourself is a software best practice that encourages you to write code once and reuse it as much as possible. The idea is that this will make your code easier to read, maintain and update.
DRY is about solving a specific problem: making it easier to modify your codebase. It’s an important goal, but it’s not the end goal unto itself.
The real goal should be to write code that is easy to understand and maintain. If you can achieve this without repeating yourself, then great! But don’t feel obligated to follow DRY at all costs.
One of the dangers of prioritizing the DRY principle is that you may be tempted to abstract too soon which often leads to inflexible code. You might unnecessarily impose certain restrictions on the architecture and make it harder to make changes in the future when you want to introduce new requirements.
Don’t rush into abstracting just because your code seems repetitive at first. You should take your time and understand all the pieces of the code and business requirements before you start abstracting. I recommend that you start using abstractions only after you are reasonably sure that the business logic of that piece is solid and the code has gone through at least a few iterations of changes.
People who are in the process of improving their coding skills often attach themselves to the idea of writing “clean” code. It is seen as the holy grail of software development. On paper, clean code is a code that’s written in a way that allows for easy readability and comprehension.
The problem with clean code is that it can cause us to obsess over insignificant details. Code style, linting rules, and other minutiae can take up a lot of time and mental energy. It can lead you to focus on these details instead of high-level software design and architecture.
It can also make you want to write a witty code that’s hard to decipher. It’s particularly tempting if you’re trying to show off your coding skills to your team.
Instead, stick to the basics and avoid “advanced” patterns unless necessary. Use
switch statements to create decision trees instead of using clever object mapping when you don’t need to.
Writing “clean” code can be subjective. In my experience, most people have different ideas about what makes code clean or not. That’s why I recommend you focus on writing code that is easy to read and understand, rather than trying to write “clean” code.
As software developers, we often tend to think big and over-engineer. But the truth is that there are very few use cases where it’s necessary - most software doesn’t need to scale at all or can be built using one of many pre-built scalable components available online.
The main danger with premature optimization is that it wastes time and effort.
Writing software that doesn’t need to scale is much easier than writing software that does, so don’t jump into scalability as soon as you feel the software is growing in size or complexity. In most cases, it’s premature optimization and will waste your time for little benefit.
Code comments are important for explaining your code to other developers - or even yourself, months down the line. However, if you go overboard with them, they are guaranteed to clutter up your code and make it difficult to follow.
If you find yourself writing many comments, ask yourself whether you could be better off rewriting the code in a more concise and readable way.
It is more beneficial to explain your code by focusing on naming variables effectively and breaking down complex functions into smaller pieces than it is to include one big block of commented text.
Comments are your friends, but only when used sparingly.
What to do instead?
So should we not use best practices at all? Not necessarily. In fact, I suggest the opposite. Dive into them, explore them as much as you want, and try to test the extent of their usefulness.
Unfortunately, the only way to learn the correct way to use a best practice is by using it the wrong way first. So don’t be afraid to use and abuse the new best practice you just learned and apply it to your code.
The critical step of the process that others often miss is to reflect on your choices. See if you’re getting a real value out of this practice. Take a step back and analyze the consequences of using it in your code.
Ask yourself whether the benefits of using the best practice outweigh the costs. If it’s not providing value, either tweak it to fit your needs or rip it out. The result is that you learned how to use the practice and, more importantly, how NOT to use it.
Software development is full of best practices - many of which we inherited from older methodologies.
It’s important to remember that not every best practice applies in every scenario, and you should always use your best judgment when making software development decisions.
If you’d like to get more web development and React tips consider
following me on Twitter
, where I share things as I learn them.