Refactoring In React

February 02, 2018 0 Comments

Refactoring In React

 

 

It is very important to work on a clean project so as to achieve flexibility to blend as per changes or additions in requirements which happens a lot in frontend applications. Many times because of reasons like delivery pressure you end up writing functional code which is not clean enough.

I observed few patterns to identify scope to refactor (code smells) during my last project work and while answering some questions on Stack Overflow in react app development.

See if your test has long and repetitive describes:

If this is the case, most probably you can separate out some code in a new reusable component itself. It helps out in moving responsibility, easier and clean testing, better code readability.

Consider these example tests for a simple form

formBefore.test.jsx

If you see the flow of tests, you will understand the thought process involved while writing a component in a TDD fashion.
My component: 
 → should have a form
 → should have three input fields
 → should have a submit button
After this much you can write tests for each input fields for their individual properties, and that will work out very nicely. Now consider that the requirement came to show error message if entered value is invalid.

You still can fulfill the requirement by doing something like

formBefore.jsx

Above code is functional and will definitely solve your problem. While testing though, you will add two more tests i.e. to check there’s no error message when entered value is correct and a test to check there’s error message when entered value is incorrect. That will be addition of two tests per input field in your form. Ask yourself, do you like doing donkey work? and want to continue doing it in future as per change in requirement?
Now now, your user/PO is super impressed by your work! And, asks for two additional form fields. How much time do you think you will spend to fulfill the requirement? Think about how many changes you will end up doing and that too in an already big code. This kind of change is more error prone and time consuming to make.

Now take a look at FormAfter

formAfter.jsx

Now think again how much time you will spend even with writing tests? All thanks to refactoring.
People who follow TDD can identify this need of refactoring easily while writing tests for the same as they end up rewriting or copy pasting same kind of tests or the whole describes itself. 
Even very small copy paste of code should trigger you to look if there’s need of refactoring.

See if you have some method call inside your tagged code:

In this case the type of code we see is a render method with some supporting method calls which are part of component only. If you have such kind of code, don’t worry you are one step ahead of others in identifying potential components, pat yourself for that.

For example consider following code:

listBefore.jsx

Imagine you continue working like this, in no time your methods will grow making your component bulky. Also this is dangerous as these methods are part of your component class and you will forget about them after switching to some other component to work with and hence it increases your chance to duplicate the same code somewhere else.
If you have such kind of code, in most of the cases you can create small components out of those functions passing them required props. If you do this sometimes you will end up creating components in fashion of container-content(e.g. a List and a ListContainer component). Let it be, creating smaller components is not at all bad. It makes your content-component highly reusable, depending on where and with what surrounding components you want to render it. It will save you from ending up with bulky components which are really big to test and even maintain.

Copy-pasting small code blocks here and there:

If you are developing a react app for at least few days I can guarantee that you have copy pasted really small code pieces from here and there.

For example:

<i className="fa fa-spinner fa-spin fa-3x"></i>

Above code will render a spinner. In single page apps we use these at so many places to show that something is loading. You can simply copy paste the above code wherever you need to use the spinner. So now you end up writing the same spinner code at least at 10 places. Looks really small right? but as you are developing more, that number keeps on increasing. Imagine, you are adding a new spinner and your designer comes and asks you to replace Font Awesome style spinner with some other style due to requirement change and that too at all places. I can imagine your reaction,

What you can do to avoid such situations is you can create a small component like this:

const Spinner = ({size}) => {
const sizeClass = size ? fa-${size}x : '';
return (
<i className={fa fa-spinner fa-spin ${sizeClass}}/>
);
};

Going ahead you can make it more flexible by blending it to accept rotation speed and rotation direction and colour. So now if same requirement comes, you end up doing change at only one place. Another similar small component that I can suggest is ErrorMessage where you want to show text with specific color and font.

const ErrorMessage = ({message, style, overrideClass}) => {
const className = overrideClass ? overrideClass : "error-message";
return (
<div className={className} style={style}>{message}</div>
);
};

Finally I want to share my learnings or you can say to do things to keep in mind while developing a react app

  • Don’t hesitate ever to create small components, instead of pushing all the stuff in a single component.
  • Keep your components small and reusable, to achieve this you can set a soft limit for number of lines in a component yourself.
  • Start with functional components, and only if needed change them to class based components (follow this specially if you are using redux) to give additional functionalities like state, i.e. try to build your components for presentation only and pull out other logic outside the component.
  • If you are following TDD, go through red-green-refactor cycle, always keep in mind to see the “refactor” part.

Once a wise man said to me,

“If you don’t clean your own shit (so called refactoring) you will end up with a big pile of shit, which you will be afraid to clean and what’s funny part is you will keep adding new shit to it unknowingly.”

Feeling inspired? Ready to do some refactoring in your code-base and make your code smile again? If yes, that’s awesome, but wait let your buddies also know about this or else there’s a big chance that you will end up something like this

Go share this with you buddies.

If you learnt something new give me some claps.

If you have identified such pattern yourself comment below, I’ll be more than happy to add it to the post.

Cheers!

P.S. You can check form component completely before and after refactoring with tests on my github here: https://github.com/swakhandekar/react-samples


Tag cloud