Pure Functions in React
During work over the past few weeks the idea of Pure Components has come up. In the first instance, a list component rendering a lot of child components was complaining in the complainer. Reacts suggested solution was to use a Pure Component to minimize the amount of rendering. In the second instance, a coworker used a Pure Component to create a static presentational component, which honestly seemed like overkill at first, but got me thinking, because outside of tutorials, I’ve never used a Pure Component.
What is a Pure Component?
In reviewing the PR that contained the pure component, I did a lot of research trying to identify the best used cases of a pure component. So, what exactly does it mean to be pure? The idea of pure components comes from pure functions, a concept of functional programming. Functional programming is a programming paradigm where functions are first class objects. Languages like Scheme, Racket, and F# fall into the category of functional programming languages. Pure functional programming languages do not have variables. Instead of assigning values functional programming languages use functions and recursion to manipulate data structures and return values.
So, to be a pure function, the function must return the same output given the same variables. If we translate this into the React world, that means given the same props, the component should return the same jsx, i.e, it should render the same thing. Therefore, there is no reason for React to render the component again if no changes are going to be made. Decreasing the amount of rendering can lead to performance gains, especially if what is being rendered is big, like a large list of items.
How Can I Create a Pure Function?
If using class-based components instead of extending React.Component, extend React.PureComponent. The difference between a regular component and a pure component class is that the pure component class does not implement the “shouldComponentUpdate” method that is used in the regular component class.2 Instead, the pure component does a shallow comparison between old and new props to determine if it should rerender.
The fact that pure components perform a shallow comparison can lead to problems if the prop that is being passed in is complex data. If an object is being passed in, for example, the shallow comparison does not examine each object to see if the values are the same. Two objects can have the same exact values but because they’re different objects the shallow comparison will evaluate them to be different. Or if the same object is passed in but its values have been mutated, because it’s the same object the component will not rerender.2
I thought React was Moving Away from Class Based Components?
Most of the React that’s being written nowadays is in the form of functional components and hooks. So, if Pure Components offer such a performance boost there must be a way to create pure components using functions, right? Yes, enter React.memo. React.memo is a higher order component that takes a component and returns the pure component version of it. Therefore if you create a functional component you can export it as React.memo(myComponent) and it will behave as if it was a pure component3. Not to be confused with the useMemo hook which can be used to memoize functions.