Simple tricks to make your code more readable

Preface

Good day, colleagues! In this article, I share my approach to code formatting, and techniques that will allow you, first of all, to better perceive your own code and navigate it, as well as other people who will work with this code.

I am Andrey Rick, a fullstack developer with 10+ years of commercial development experience, developed many startups in various teams, and developed several startups alone, including my own. I will demonstrate code examples on React/Next, at the same time, this approach can be applied to any of the programming languages ​​and frameworks based on them.

In the process of implementing the concepts I have proposed, you are highly likely to encounter the fact that the code will look unusual to you, and your internal conservatism will push you to write the code “the old way”.

However, believe me, if you can afford to go through the adaptation, the code that does not correspond to these design concepts will disgust you, because it will resemble a stuck together porridge that is difficult to perceive. In addition, in the article I do not just describe the techniques, but also tell why it is necessary.

We design the code: how and why?

Orderly, neat, well-written and easy-to-read code helps to detect random errors faster, and allows the eyes to “parse” code, that in general speeds up task execution time. Besides this, there is another non-obvious but significant advantage:

When you write code neatly right away, you manifest a certain attitude through yourself – to your work activity, to the process, to yourself. Order in the code = order in the soul (the same applies to the workplace). This approach begins to spill over into all other areas of your life, helping you practically in everything (this is really true).

This forms a certain way of thinking that can be developed in oneself, even if it is not there initially. From a state of order (in the head, in affairs, and ultimately in one's own code), work goes easier and faster, bright ideas come more often, and the general state and perception of the world significantly surpasses work from a state of chaos.

This only works if you consciously independently write your code neatly, and do not rely on prettier, which is supposed to “do it for you” but in some cases It hinders rather than helps.

Don't be afraid to spend extra effort on order and neatness in your code. Once you've learned to write neat code, you don't need to put in any extra effort – it happens by itself, you don't know how to do it any other way. And nothing will make you write code the same way again.

Nesting in code:

All levels of nesting in the code are separated by tabs and empty lines.

What are nesting and nesting levels?

Nesting:

When we have an opening bracket and a closing bracket, everything between them is considered nested in them. When we have an opening and closing tag – everything inside is nesting of this tag. When we write tag attributes inside the brackets of the tag itself – the attributes are also nesting within the brackets of the tag.

Nesting levels:

Both brackets and tags can themselves be inside brackets or tags, in which case they still open a new level of nesting. There is no limit to the number of nesting levels.

This applies to layout, functions, styles, JSON objects, and all code in general.

An example of separating nesting with tabs and blank lines

Example nesting separations tabs and blank lines

Inside the code the same level of nesting We only need an empty line in two situations:

When next line with code opens a new one nesting level, or previous line with code closes new nesting level:

Example when you need an empty line within the same nesting level

Example when you need an empty line within the same nesting level

Example when you need an empty line within the same nesting level

Example when you need an empty line within the same nesting level

The second situation when we can add an empty line is to separate logical code groups within the same nesting level:

An example of separating logical groups of code with a blank line within the same nesting level

An example of separating logical groups of code with a blank line within the same nesting level

In this situation, when required separate with blank lines inside one and the same nesting level, end.

That is the concept not in thatso that after each “non-empty” line there is an empty line. Like in the screenshot below, do NOT necessary:

This is NOT how you should do it! The concept is not to do it after each "not empty" line was a blank line. If the concept is not clear at this point, reread the contents of the article.

This is NOT how it should be done! Concept not in thatso that after each “non-blank” line there is a blank line. If at this point the concept is not clear, reread the contents of the article.

Now let's look at when we should create visual nesting, and when we can place nesting on one line.

We can write nesting in one line if its contents take up little space and contain no more than 2, figuratively speaking, items:

for such a case there is no need to move this nesting to a new line and separate it with empty lines

for such a case there is no need to move this nesting to a new line and separate it with empty lines

Here, too, there is no need to move these nestings to new lines and separate them with empty lines - since the contents of the nestings do not take up much space and contain no more than 2 items.

Here, too, there is no need to move these nestings to new lines and separate them with empty lines – since the contents of the nestings do not take up much space and contain no more than 2 items.

However, when we have many elements in nesting, It will be much clearer if you place each element on a new line.

In what situations might this be relevant:

When a component is passed many (more than 1-2) props (or HTML/JSX tag attributes), for clarity, you should not write them in one line!

When a component is passed many (more than 1-2) props (or HTML/JSX tag attributes), for clarity, you should not write them in one line!

When we have a very long className, it should not be written in one line, moreover, it can be broken down into logical groups/conditions, each on a new line. See for yourself how much clearer the code below is than the code above (the code above does not fit into the visibility field completely)

When we have a very long className, it should not be written in one line, moreover, it can be broken down into logical groups/conditions, each on a new line. See for yourself how much clearer the code below is than the code above (the code above does not fit into the visibility field completely)

When we destructure many properties from an object

When we destructure many properties from an object

I have conveyed the main essence of the design of nesting, below I will give several examples of how, from my point of view, it is best to design the code of frequently encountered techniques:

Variations of the classic If else
The optimal option takes up a minimum of space, while at the same time providing visibility of nesting

The optimal option takes up a minimum of space, while at the same time providing visibility of nesting

If the conditions require one thing to be done, and it doesn't take up much space, you can write it like this:

If you need, for example, to interrupt the execution of a function if some condition is not met, and the main logic should be executed if the condition is met, instead of creating unnecessary nesting with the if else construct, you can handle the failure of each condition with just one if, and continue writing the main logic at the same nesting level. It is easier to understand with an example – just compare these two approaches:

The code on the right looks too voluminous and complicated, it distracts from the essence, and such code takes longer to perceive. The code on the left implements exactly the same thing, but looks concise and understandable.

The code on the right looks too voluminous and complicated, it distracts from the essence, and such code takes longer to perceive. The code on the left implements exactly the same thing, but looks concise and understandable.

If a large number of conditions are checked in if, it makes sense to visually separate them, for example, like this:

Visual complex logic

Visual complex logic

Thenar “if && then” and “if ? then : else then” conditions in JSX output
This type of writing of the component output by condition gives both a clear understanding of nesting and takes up a minimum of space

This type of writing of the component output by condition gives both a clear understanding of nesting and takes up a minimum of space

This format of writing gives a clear understanding of where each condition begins and ends, where this or that result of the condition begins and ends

This format of writing gives a clear understanding of where each condition begins and ends, where this or that result of the condition begins and ends

It makes sense to write part of the condition in one line when either the entire expression is short, or we are dealing with a large main part that is output by the condition, and if the condition (true/false) should be output some small, insignificant part, and in this case we write the small part on top of the expression:

Example of JSX output via map, and examples of useEffect
Outputting JSX via map

Outputting JSX via map

useEffect example with deep nesting

useEffect example with deep nesting

useEffect example with short nesting

useEffect example with short nesting

Separate functions, components, styles into different files

Don't write styles in the same file where the component code is located (relevant for styled-components). Thanks to this, when you explore the code and fall into functions/components (by clicking on their name with ctrl or ⌘ pressed), you will not lose focus from the current component, jumping to another part of the file, but instead another file will open, which you can drag into a separate section of the code editor, and work with both files simultaneously. Don't write several components in one file for the same reason.

Moreover, do not create components inside the code of other components – this not only increases the volume of code (and the complexity of its perception) inside one file, but also from the point of view of optimization is “not ok”.

If your page consists of several parts that can be separated into independent components – do this, do not write the entire “layout” in one file. Then call these components – and you will see how the code has become much easier to understand. Just compare:

Here we just stuffed the entire layout into one file. So what? It works anyway! (don't do that)

Here we just stuffed the entire layout into one file. So what? It works anyway! (don't do that)

And here we have divided the parts of the page into components, and looking at this code we immediately understand what is where. We will easily be able to find and change the necessary section if necessary.

And here we have divided the parts of the page into components, and looking at this code we immediately understand what is where. We will easily be able to find and change the necessary section if necessary.

Try to make components and functions universal and reusable. Think about how to cover and implement most of the project's functionality with less code, and when.

Do not duplicate code under any circumstances – create simpler functions/components, and expand them with functions/components that are based on the functionality of simpler ones (i.e. they use imported simpler functions/components, and logic is built on them, and this set in turn is a separate function/component). This is also a fairly broad topic, and to a certain extent is an art. If you are interested and relevant, you can write about it in the comments, maybe I will somehow upload a separate article on this topic.

Each file with a component of a certain type, function, or something else, should be in its own folder. That is, you should (for yourself) create such a file structure to clearly understand that if you need some component, where to look for it. This is a very broad topic for a separate article, for this reason I do not specifically cover it here, just take it as an idea.

But for React/Next I have already written an article about it, so anyone who develops on this stack can see in practical examples what exactly I mean, and how I personally approach organizing a clear file structure in the projects I work on.

Clean your code from “garbage”

Remove unused imports, variables, functions, extra blank lines (when there are two or more blank lines instead of one), blank lines at the bottom of the file, comments that are no longer useful to you, and commented-out backups of code that you will never need (we are talking specifically about cases in which this code really will not be useful).

Don't use “magic numbers”

It is better to create an “extra” variable and name it according to the meaning of the value contained in it. Just compare:

What is that one on the left?? But on the right, everything is immediately clear, even when you first look at the code!

What is that one on the left?? But on the right, everything is immediately clear, even when you first look at the code!

Above - "magic numbers"which don't say anything. From below - everything is immediately clear, and by falling into the MATERIAL_TYPES constant you can see what values ​​there are and what they refer to.

Above are “magic numbers” that don't mean anything. Below is everything clear, and by going into the MATERIAL_TYPES constant you can see what values ​​there are and what they refer to.

Good luck in developing your projects!

Let your code be clear and understandable for you and your colleagues, and let there be order everywhere – from your code, project structure, workplace, and ending with your head and all your affairs!

Even if it's not like that now, or not like that everywhere.. Take a step towards positive change. Start with code.

All of the above is my personal subjective opinion and vision of the situation. It does not necessarily have to coincide with your opinion and vision.

I have described perhaps the most important, from my point of view, aspects of code design and ensuring its clarity. Using this approach significantly affects my perception of the code, the speed of work, the feeling of harmony and pleasure from the development process. If the article is useful for you – I am very glad.

I will add to the article if I remember any more examples. In general, there is still something to share both on this topic and in general. See you in the next articles!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *