Anti-patterns
Introduction to anti-patterns
Last updated
Was this helpful?
Introduction to anti-patterns
Last updated
Was this helpful?
Familiarizing ourselves with common anti-patterns will help us understand how React works and describe useful forms of refactoring our code.
are certain patterns in software development that are considered bad programming practices. As opposed to design patterns which are common approaches to common problems which have been formalized and are generally considered a good development practice, anti-patterns are the opposite and are undesirable.
While rendering a list of similar components, keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity. And most JS developers tend to use array index as key which can be considered as an anti-pattern.
Here is an official documentation from :
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort.
Here's a blog explaining why an index as key is bad practice:
Keys should be stable, unique & predictable. Index, random numbers or timestamps.
When defining constants, we have to decide the placement in the component. Most developers tend to define constant object literals and arrays inside the render methods in react. This approach might affect the performance and the lag can be visible in large components.
When you want do define some constants for images & styles, it is advised to define outside the component.
We also can define the constants inside constructor.
In class based components, componentWillReceiveProps (to be deprecated) & getDerivedStateFromProps offer a way to update state in response to the change in props.
A common misconception is that getDerivedStateFromProps and componentWillReceiveProps are only called when props “change”. These lifecycles are called any time a parent component re-renders, regardless of whether the props are “different” from before. Because of this, it has always been unsafe to unconditionally override state using either of these lifecycles. Doing so will cause state updates to be lost.
In above example, state is updated based on props received. But if the component’s parent re-renders, any update to the state will be lost.
State management libraries like redux maintaining single source of truth.
Data down action up approach can be used which emphasizes unidirectional data flow. This approach prioritizes passing down data from one part of application down its children components. The children component has readonly access to the data but it cannot modify the data directly. Instead, the children component can have access to actions or callbacks which can be used to update the data in parent component.
Developers working with promises
and async await
in JavaScript can make common mistakes which can introduce confusing blogs in an application.
This makes it difficult to refactor the codebase and nesting of promises can introduce bugs if not handled correctly. A cleaner way could be use of promise.all
In case you are using async await
async await
in a function blocks the execution of the code until the response is resolved. So, if the variable does not even depend on the promise to be resolved, it can be considered as an anti-pattern as in above example.
The setState is pretty simple & straight forward concept in React. But developers might over look some of the nuisances when using setState
Consider the following:
The setState
method is asynchronous. Hence, we should not use the use the value state itself inside setState
as above.
We can use the following syntax to avoid the issue:
prevState
is a name that given to the argument passed to setState
callback function. It holds is the value of state before the setState
was triggered by React.
It is necessary that we use async api calls using useEffect
hook. So, we might be inclined to write something like this:
We should always use multiple useState
hooks instead of one big one like in setState
because the react hooks has changed how react internally handles updates to objects within the state. In class based components, calling setState
would merge new values into the existing state object.
If there were keys whose values had not changes, there would not be any need to replace the existing values at those keys. However, useState
hook entirely replaces the underlying value. If we had an object with all state properties, we would be replacing the entire state on every update with useState
hooks. So, we need to split of states into multiple hooks so that the react engine replaces the states in isolation.
According to , The async function declaration defines an asynchronous function, which returns an AsyncFunction object. However, an effect hook must return nothing or a clean up function. We then get a warning about useEffect
must return a cleanup function or nothing. The correct approach would be as below: