Common React Mistakes And How To Avoid Them
Vishnu K G
Introduction
It’s usually advisable to examine common mistakes made by other developers when starting out with a new language, framework, or tool. This allows you to consciously sidestep these errors and prevent them from happening in your own work.
In this regard, we’ve compiled a list of common React mistakes, ranging from minor issues like using “class” instead of “className,” to more subtle mistakes like unintentionally modifying state directly instead of utilizing the “React” method. Let’s explore these errors without any particular order.
Not Using Keys Properly
Proper usage of keys is crucial in ReactJS to identify individual elements in a list. Neglecting to utilize keys can prompt ReactJS to generate a warning, potentially leading to suboptimal application performance.
To prevent this error, it’s imperative to always implement unique keys when rendering lists. The below example show how we write code without using Key
This will render a list with items. However, if you look at the React Developer Tools, you will see a warning in the console:
This warning is telling you that you should use a unique “key” prop for each ListItem component, so that React can keep track of which items have changed, been added, or been removed.
If you don’t use keys, React may have to re-render the entire list every time a change is made, which can be slow and inefficient. To fix this, you can add a unique key prop to each ListItem component:
In this example, we’re using the index of each item in the array as the key. While this is not the ideal solution (because the order of items could change), it is better than not using keys at all. Ideally, you should use a unique identifier for each item in the list, such as an ID or slug, as the key
Over Using setState()
Updating the state of a component is a crucial aspect of ReactJS, and it’s accomplished using the setState() method.
Nonetheless, excessive usage of setState() can negatively impact performance. To prevent this issue, it’s recommended to batch state updates by utilizing the functional form of the setState() method.
This ensures that multiple state updates are executed within a single render cycle, optimizing the performance of the component.
Here’s an example of overusing setState() in React:
In this example, we have a simple component that displays a counter and a button. Clicking the button increments the counter by 3.
However, if you look at the code closely, you’ll see that the handleClick() function calls setCounter() three times in a row, with the same value each time. This is not only unnecessary, but it can also lead to performance issues
When you call setState(), React queues up a re-render of the component. If you call setState() multiple times in a row, React will queue up multiple re-renders, even if the state is not actually changing.
In this example, it would be more efficient to call setCounter(counter + 3) instead of calling setCounter() three times. This way, React only needs to queue up one re-render instead of three.
In this revised example, we’ve reduced the number of calls to setCounter() and improved the performance of the component.
Not Using React.memo()
Using React.memo() is a recommended technique to enhance a component’s performance.
It’s a higher-order component that memorizes the component, allowing it to re-render only when its props are modified.
To prevent unnecessary re-renders, it’s advisable to use React.memo() for components that don’t require frequent re-rendering.
Here’s an example of not using React.memo() in React:
In this example, we have a parent component ParentComponent that renders a child component ChildComponent. The child component receives a prop name from the parent component, which is used to render a simple div.
However, if you open up your browser’s console and type in the input field, you’ll see that the console logs “Rendering [name]” every time a keystroke is entered. This means that the child component is being re-rendered every time the parent component’s state updates, even if the name prop hasn’t actually changed.
This is where React.memo() comes in handy. React.memo() is a higher-order component that memorizes the result of a component’s rendering, preventing unnecessary re-renders.
To optimize the ChildComponent’s rendering and prevent unnecessary re-renders, we can wrap it with React.memo() like so:
In this revised example, we’ve wrapped the ChildComponent with React.memo(), which memoizes the rendering result of the component. Now, if you type in the input field, you’ll see that the console only logs “Rendering [name]” when the name prop actually changes, and not on every keystroke. This optimizes the performance of the component and reduces unnecessary re-renders.
Not Using PropTypes
PropTypes is a library for typechecking that aids in preventing application errors. It validates the type of the props provided to a component and issues a warning if the type is incorrect. To prevent this issue, it’s advisable to utilize PropTypes to verify the types of the props passed to a component.
Here’s an example of a component that doesn’t use PropTypes to validate its props:
In this version, we’ve imported PropTypes from the prop-types library, and added a propTypes property to the component. This property defines the expected types of the component’s props, as well as any required props.
Now, if someone were to pass in a prop of the wrong type or forget to pass in a required prop, PropTypes would issue a warning in the console. This can help to catch errors early on and make debugging much easier.
Not Using the Correct Event handler
ReactJS offers a variety of event handlers, including onClick, onSubmit, and onChange, among others. Choosing the right event handler for each event is critical to guarantee the application’s proper functioning. To prevent this mistake, it’s important to use the suitable event handler for each event.
Here’s an example of a component that doesn’t use the correct event handler:
In this example, we have a TextInput component that receives a placeholder prop and uses the useState hook to manage its internal state. However, the onChange event is used to capture changes to the input value, which is not ideal. The onChange event fires on every change made to the input, which can cause performance issues if the component is re-rendered frequently.
Here’s an updated version of the same component that uses the appropriate event handler:
In this version, we’ve replaced the onChange event with onInput, which fires when the user finishes typing in the input. This reduces the number of unnecessary re-renders and improves the component’s performance.
Not Using Pure Component
The PureComponent is a fundamental class that incorporates the shouldComponentUpdate() method. It’s useful in enhancing the performance of a component by reducing unnecessary re-renders. To prevent this mistake, you can use PureComponent for components that do not have any frequently changing internal state or props.
Here’s an example of a component that doesn’t use PureComponent:
In this example, we have a UserList component that fetches a list of users from an external API and renders them as a list of names. However, the component extends the Component class, which means that it will re-render every time its state or props change. This is not optimal for a component that doesn’t have any internal state or props that are likely to change frequently.
Here’s an updated version of the same component that uses PureComponent:
In this version, we’ve replaced Component with PureComponent. This means that the component will only re-render if its props or state have changed. Since the UserList component doesn’t have any internal state or props that are likely to change frequently, this will result in fewer unnecessary re-renders and improved performance.
Using a class instead of className
This one is short and sweet, and we can attribute this very common React mistake to muscle memory alone.
Writing:
Instead of :
This is a minor mistake that I’m sure the vast majority of React developers have made at one time or another!
Using a lot of Inline Style
The best way to style React components is hotly debated, and there are various different avenues that one can go down in this regard.
However, using a lot of inline styles is almost certainly a mistake. Inline styles look a little bit like this:
So simply put, these are effectively CSS styles applied to the element directly via the style prop.
Inline styles do have their usages — but relying on them too much will undoubtedly make your components unwieldy and hard to manage and maintain in the long run.
It’s much better to opt for a more scalable approach. There’s nothing wrong with using regular CSS in this regard, but a solution like styled-components would be considered the most optimal approach by many.
Creating god Component
Creating components that are too big and too complex is certainly one of the classic React mistakes, particular among beginners.
At first, if your application works — it’s only natural to assume that your components are fine and fit for purpose.
However, you’ll soon realize that components that are too complex become hard to maintain in the long run. This ultimately makes your application harder to manage and harder to scale. The code becomes unwieldy and needlessly difficult to work with.
Instead, focus on small, modular components that have a specific job.
Think of components like building blocks.
Where possible, they should be reusable. It should be straightforward to drop the components into other positions within your application, and they should still function as expected or required
Conclusion
Using ReactJS library efficiently is crucial in building performant, scalable, and maintainable user interfaces. By steering clear of common mistakes, developers can make the most of ReactJS’s potential. In this blog post, we covered some of the frequently encountered ReactJS blunders and recommended ways to sidestep them. By incorporating these best practices, developers can enhance their ReactJS coding skills and construct top-notch web applications.