Transform a React functional component into a Pure component without the need of using the class PureComponent from React
How many times have you transformed a simple functional component into a Class one because you needed to be Pure?
This adds more lines of code, and every line of code has a cost — to write, to debug, and to maintain.
Fortunately, you can achieve this behavior thanks to recompose. It’s a functional utility belt for React, providing, for instance, the pure()
HOC.
Now instead of export the component we can do export default pure(componentName)
an this will be pure without transforming to a class-based component.
You can even implement the shouldComponentUpdate
logic and other interesting behaviors like only update for specific keys.
Component will only update for specific keys.
import onlyUpdateForKeys from ‘recompose/onlyUpdateForKeys’
const componentName = ({ resource, ids, data, children }) => (
...
);
export default onlyUpdateForKeys([‘ids’, ‘data’])(componentName)
Be more specific and target only the props that I know may change
import shouldUpdate from ‘recompose/shouldUpdate’
const componentName = ({ resource, ids, data, children }) => (
...
);
const checkPropsChange = (props, nextProps) =>
(nextProps.ids !== props.ids ||
nextProps.data !== props.data);
export default shouldUpdate(checkPropsChange)(componentName)
Make your component pure even if is not a class based component
import pure from ‘recompose/pure
const componentName = ({ resource, ids, data, children }) => (
...
);
export default pure(componentName)
React.memo
is a higher order component. It’s similar to React.PureComponent
but for function components instead of classes.
const MyComponent = React.memo(function MyComponent(props) {
/* render using props */
});
If your function component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.
By default it will only shallowly compare complex objects in the props object. If you want control over the comparison, you can also provide a custom comparison function as the second argument.
function MyComponent(props) {
/* render using props */
}
function areEqual(prevProps, nextProps) {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
}
export default React.memo(MyComponent, areEqual);