Definition 🤓
A component is said to be pure when given the same props, it always renders the same.
A non-pure component can, given the same props, render differently.
import React, { FC } from 'react';
type DiceProps = {
value: number,
};
const Dice: FC<DiceProps> = ({ value }: DiceProps) => (
<span>
{value}
</span>
);
type DiceRollerProps = {
numberOfDices: number,
};
const DiceRoller: FC<DiceRollerProps> = ({ numberOfDices }: DiceRollerProps) => (
<>
{Array.from({ length: numberOfDices }, () => (
<Dice value={Math.ceil(Math.random() * 6)} />
))}
</>
);
export default DiceRoller;
Two components in this example : DiceRoller
and Dice
.
Dice
is a pure component ✅
DiceRoller
is not a pure component ❌
The DiceRoller
component randomly rolls new dices on each render,
the only purpose of the Dice
component is to render the dices.
If numberOfDices
equals 4
, DiceRoller
will roll four dices and will keep doing so everytime it re-renders.
Rolling the dices with Math.random
makes the result of the render unpredictable.
DiceRoller
is not a pure component, since given the same prop, it can render differently.
Dice
, on the other hand, only renders the value it receives as prop. Given the same prop,
it always renders the same, which makes it a pure component.
The purity of a component is inherent to its implementation 🧬
There is nothing wrong with a component not being pure. It just means that it needs to re-render no matter
whether its props have changed or not.
Inversely, a pure component does not need to re-render if its props have not changed. This way,
it can be optimized by skipping re-rendering.
Optimizing a pure component ⚡️
One way to optimize a pure component is to prevent it from re-rendering if its props have not changed*,
* To know whether the props have changed or not, React performs a shallow comparison. It means if your component receives props with complex data structures (such as nested objects), the comparison may result in a false-negative.
(cf. shallowEqual)
A class component can be optimized by creating it from the React.PureComponent
base class.
A function component can be optimized by wrapping it into React.memo
function.
import React, { FC, memo, PureComponent } from 'react';
export class MyClassComponent extends PureComponent {
...
}
export const MyFunctionComponent: FC = memo((props) => {
...
});
Conclusion
A React component is pure when, given the same props, it renders the same.
This means the purity of a component is inherent to its implementation.
Class or function pure components can be optimized using respectively PureComponent
base class or memo
function.