13

React the Wrong Way: 4 Anti-Patterns to Avoid

 2 years ago
source link: https://blog.bitsrc.io/react-the-wrong-way-4-anti-patterns-to-avoid-2d68a28aac00
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

React the Wrong Way: 4 Anti-Patterns to Avoid

What to do if you want to create a terrible React-based application

Ever wondered if you’re actually using the tools at your disposal in the right way? Sometimes tool makers will give you a brief guide on what they do and how to use them, but they won’t enforce a specific way to use them on you.

You’re then free to decide if you grab the hammer by the end or closer to the head. However, while the hammer makers (if that’s even a thing) won’t specify it, there is a right way and a wrong way to use their tools. And the same happens with React.

Just because you’re able to use create-react-app to bootstrap your React application it doesn’t mean you’re doing it the right way.

Lucky for you, I’m here to show you different ways in which you should not use React. Pay attention, and if you find yourself reflected in these anti-patterns, find a better way, your future colleagues will thank you.

1. Nested components

Also known as scoped components.

When writing components sometimes we might be tempted to nest them like this:

It makes sense after all, since childComponent is not going to be used outside of MainComponent and it can already use the name state variable without having to receive it as a prop. However, this nesting of functions actually generates a small performance issue.

You see, every time your MainComponent component is called (i.e rendered), it’ll re-create the childComponent component’s definition. So it’ll keep on declaring the same function over and over again on every execution. Mind you, if you’re not doing this everywhere, it might be a small issue that you might not even notice affecting your performance. However, left unchecked, this is a terrible practice.

Remember kids: don’t over-define your functions/components if you can only define them once and use them many times.

2. Rendering FOR loops with a variable index

We’ve all been there, having to render a list of things and quickly relying on the handy syntax shown below:

The example is simple, but notice how we’re using the index variable provided by the map method. We need to provide a key to our elements, so we might as well use this one right?

Wrong.

Mostly because you’re hardly ever rendering such a simple list. In fact, you’re usually rendering a list of things that might change, be re-ordered or are more complex than just a string. And what happens then? The value of key is used by React to understand when an element is added, changed or removed. It is meant to act as a unique identifier of the element and not a simple index within the list.

While you might think that in our example the index used actually acts as an ID, consider what would happen if we were to add more elements to the list of users but not at the end. Instead the new index values would reference different users thus a different component (a different li element). React would get really confused and generate unexpected behaviors. You can read more about why this is a big problem in this article.

But remember: take the time to generate a unique ID for all your elements, it’ll save you a lot of headaches.

3. Having large component trees inside the same component

It’s a bit of a tongue twister, but the gist of it is that having components returning huge trees is never the right move.

Something like this makes it very hard to understand and debug:

It might not seem like much, but you’re dealing with a lot of logic that shouldn’t be inside the same component. I mean, yes, you can do it if you want, everything will work, however, you will have a lot of logic that could’ve been moved out, simplifying the overall complexity of your component.

Even further, an approach like the one shown above could lead to you coupling the logic of different components together, simply because everything is defined inside the same function.

You could potentially extract the navigation buttons out into another component and each one into its own individual component as well (if you think it could help) and finally, the bit of logic deciding whether to greet the user or not could also be extracted. The point here is that your components should be atomic, they should only worry about a single responsibility and everything else should be done through the use of other components.

That way you’re composing them together, gaining flexibility and freedom to extend and expand each one individually without affecting others.

4. Using context to handle global state management

In some situations the line between state and context might become blurry. Or blurry enough to confuse some developers. However you would do good to remember that they are two very different things, meant for different use cases.

Context allows you to share props between related components, helping you avoid the dreaded “prop drill down” effect, where you have to pass the same prop through 4 different levels just to get to the actual component that needs it.

Global state, on the other hand, is meant to handle values that are common to the entire application.

If you wanted to use context in this situation, you’d have to create a context provider to wrap your entire application in. Which would go against the entire purpose of said constructs.

Just like with all other examples in this list, you can perfectly use context to handle global state management. However, once you start doing it on an ever-growing application, things will get out of hand.

In closing

It’s hard to see the problem with anti-patterns when you’re dealing with a small enough application. At that stage, most of these are just small differences in the way we interpret the official documentation. The real problems begin once the application starts growing and these “small differences” become too big to ignore.

By then, they start affecting your logic, or your performance and fixing them would require a big refactor. This is why anti-patterns should not be ignored, no matter what kind of application you’re working on.

Write scaleable, modular components with Bit

Instead of building monolithic apps, build independent components first and compose them into features and applications. It makes development faster and helps teams build more consistent and scalable applications.

Bit offers a great developer experience for building independent components and composing applications. Many teams start by building their Design Systems or Micro Frontends, through independent components.
Give it a try →

An independently source-controlled and shared “card” component. On the right => its dependency graph, auto-generated by Bit.

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK