Erma M. Coley
One mistake React developers often make is that they don’t create enough components.
Generally, there are two ways of writing applications: putting everything in one place (monolith), or splitting everything into smaller pieces (micro-services).
By design, React applications are meant to be componentized. To build a dashboard correctly using React, we would have to think of it as a set of components that form a page rather than a complete page itself.
That way, we can create different sets of components that — when put together — make up the whole page.
This technique not only saves you time, but it also saves you a lot of stress when debugging since you’ll instantly know which component is associated with each error.
When searching for a proper way to create components for reusability, the presentational and container component creation pattern is often one of the first to show up.
Presentational components are associated with how things look, while container components are associated with how things work.
A common mistake you’ll see in React applications is that presentation markup and app logic are fused into one component.
The downside of this approach is that you cannot easily reuse any of the components or logic without copying and pasting.
If you use the presentational and creation pattern, you can achieve reusability of both the markup and logic more easily. You can also make UI changes without messing up the behavior.
Mutation is the ability to change something.
However, the best approach is immutability. You can either implement it yourself, or use Immutable.js and immutability-helper, which is recommended by the React team.
If you have ever worked on a React application that has many components, images, CSS files, and other files, you’ll agree that importing files from different directories can be tedious.
We can already see that it isn’t neat, and changing the directory of a file will cause the import to fail. With the release of Create React App 3, we can now use absolute import paths.
Not only is this cleaner, but it also means you don’t need to update the path in your code after changing the location of a file.
We often run into situations where we would need to render a list of items.
For smaller applications, this may work. But when working with large lists, you’ll run into render issues when you try to modify or delete an item from the list.
React keeps track of each of the list elements on the DOM. Without it, it would not know what has changed in the list item. To fix that, you need to add a key to all your list elements.
This is one of the most common mistakes out there. It’s frequently overlooked because applications can still technically work without unit tests. A Unit Test allows you to test parts of your application independently to ensure a certain functionality works as expected.
For instance, you can write a unit test to check if a prop passed to a component was rendered on the browser. You may wonder why you’d write such a small test. Sometimes you expect your prop to display properly after writing your components, but occasionally a conflicting CSS style may block it from displaying.
Writing a unit test saves you the time you’d spend tracking down that bug by pointing it out immediately (failing). They help you debug quickly across your application.
I often see incorrect data types being passed around in applications. Defining the types via the prop-types package is the most reliable way of making sure you send the right props.
Prop-types are used to document the intended types of properties passed to components. React will check props passed to your components against those definitions, and warn in development if they don’t match.
This is a common mistake I’ve seen in many React applications.
In addition to reusable components, we also have reusable functionalities in our applications.
This functionality is often hardcoded on a component-to-component basis, which leads to inefficient and inconsistent behavior between similar components.
All container components contain logic to grab a resource, save it to state, and manage errors.
Most times, this behavior is the same from one container component to another, but it can behave inconsistently when not written properly.
Consider the example above where we make an API call to grab a resource, set the state, and also handle errors.
If we extract that behavior to a helper class or function, we can reuse the same logic for API calls, setting state, and error handling.
In bigger React applications, a lot of developers use Redux or Flux to manage global state. This is very useful, especially when various parts of the application will benefit from having a shared state.
However, it’s inadvisable to use Redux or Flux to manage every state in your application.
Take, for example, a form component. If we want the state of a check button to always be checked whenever we visit it, the best approach is to manage it using local state method or useState (for Hooks) rather than using Redux or Flux.
Applications always get buggy after a while. Debugging is often a lot of work, since most of the time many components are involved.
With React Dev Tools , you can inspect the rendered tree of React elements, which is incredibly useful for seeing how various components build up a page.
The Redux Dev Tools also come with a host of features that let you see every action that has happened, view the state changes these actions caused, and travel back to before certain actions occurred.
You can add React dev tools as either a dev dependency or as a browser extension.
Using them will save you a lot of development time.
Please comment other common mistakes that I have missed
Thank you!
I build websites that delight and inform. I do it well. I’m curious, and I enjoy work that challenges me to learn something new and stretch in a different direction. ErmaMColey@rentfamily.com