Everyone loves a good list, myself included. This guide tells you a list of 10 principles that you can follow that will help you write better React applications
- Naming Is Very Important A fact in life is that developers spend more time reading code than writing it. When write code is hard for another developer to understand it will take them longer for them to update the code. Having good names prevents this.
When it comes to writing easy to understand code within react there are a number of things you should consider:
- Use descriptive names for methods
- Use descriptive names for variables, parameters and arguments
- Use capital letters for component names, so 'MyComponent', not 'myComponent'
- Avoid acronyms in names unless everyone on a team understands them
A common rule to think about naming is that components should be named after its function.
- The DRY principle Do Not Repeat Yourself is a mantra I try to adhere to. If you have code that duplicates the same functionality dotted throughout your codebase you will spend time writing extra tests, you will spend more time maintaining your codebase and the chances of introducing bugs between the duplicate code increase.
One thing to be wary about is that it is easy to follow this pattern too much. A good rule of thumb is that if code is duplicated in three places you should invest the energy to refactor it.
Ask For Help Asking for help is a double-edged sword. Every-time you ask for help you rob yourself of an opportunity to hone your analytically trouble-shooting skills. Try to solve your own problems will give you confidence in moving forwards. After a few hours if you are not making progress do not be afraid to ask someone for help. If you feel confident you have done everything you can to solve a problem then ask someone to help. Out of all the teams I have worked, it is very rare that someone will not want to help someone out.
Keep Your Components Simple Within React the smaller the component the easier your life will be. Testing is kept simple. Reuse is possible. A smaller component can usually be optimized for performance easier. As a project evolves it is easy for a component to accidentally grow to ungainly size. This tends to happen when the responsibilities of a component grow. Normally when a component gets too big if you take a step back it is usually obvious where it can be split into smaller components. Applying techniques like higher-order components can be useful. Applying the container/presenter pattern can also be used.
The Boy Scout Rule The boy scouts have a motto. “Always leave the campground cleaner than you found it.” If you encounter a mess you should clean it regardless of who made it. When you work within a code-base if you apply a constant rule for making small incremental improvements on every pull-request the code will constantly evolve and improve.
The longer you leave a code-smell within the code-base the harder it will be to remove later on. Constant never ended little improvements will have a drastic improvement on the quality of your code-base
- Separate Stateful Logic From The JSX It is very easy to overcomplicate components. Imagine you have a need to call some data from an API and render the data within a list. One way to solve the problem would be to build a single component that would add the fetch and return all JSX within a single component. This approach would work but the component would be very brittle. The JSX could not be used anywhere else without the data-fetching logic present.
A better way to handle component architecture is to apply the container/presentation pattern. In this approach, the API code is wrapped on one component. The JSX is then added in a very simple presentational component that has no/minimal logic within it.
Favour functional components Writing a component as a simple function rather than a class component will result in cleaner code. As of React 16 and the introduction of hooks pretty much anything you can do within a traditional Component or PureComponent you can do within a functional component. Leveraging 'useEffect' and 'useState' you can add state and life-cycle methods.
Test Behavior Not Implementation Details Have you have worked on a project where you need to make a small change. The change takes 10 minutes and is simple. When you come to run the tests the change has resulted in numerous failure. Next thing you know you spend more time fixing the tests that the original change took? If this has ever happened to you then chances are you have written tests that are testing implementation rather than behaviour.
Imagine you have a button component. and you want to write ensure the correct label is displayed. In this scenario, you do not care what props are passed or how they change. All you want is a test that ensures the label works. These types of tests can be difficult to write using 'Jet' and 'Enzyme'. In these situations, it is better to use a library like react test library. Using react test library you write your tests against the components outputted DOM nodes. This decoupling of tests from props will make your code a lot less brittle and easier to maintain.