Side Effects of Optimising Without Profiling
There are so many new things that have come out recently, to help developers write better code in the react. But as with everything, there is no “silver bullet”. Everything has a cost and we need to be smarter about evaluating the tools we use.
So let’s start…….!!!!!
High order component
HOC technique to reuse a component logic in react, and basically HOC is a function that takes a component and returns a new component.
and it’s very helpful for reuse the component logic and render hijacking let’s check for example.
const nameHoC = WrappedComponent => {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
}
componentDidMount() {
this.setState({name: "Chirag"});
}
render() {
const {name} = this.state;
return(
<div>
<WrappedComponent{...this.props} name={name}/>
</div>
)
}
}
};
export default nameHoC;
Here nameHoC is a function that is taking WrappedComponent as an argument and returning a brand new component by adding some new features to WrappedComponent. We are passing the name as a prop to WrappedComponent.
const WishMe ({ name }) => {<h1>Hello {name}! Good morning</h1>}
export default nameHoC(WishMe);
As you can see here, we have imported nameHoC and wrapped theWishMe component in it, nameHoC(WishMe). In WishMe we are using data from props to get the name of the person to wish
What’s great about higher-order components is that you can see the data coming into the component as a prop. It is no longer magical like with Mixins.
However, there are issues. The main problems with higher-order components include:
- They are complex to setup.
- You can not distinguish between data that was coming from the HOC and the data that was passed to the component.
- The HOC is external to the component yet the component remains dependent on the HOC. Remove the HOC and the component would not always work if it depends on the HOCs data.
- You can end up with huge render trees as behavior components contain render components.
React.memo
React.memo() is similar to the Pure component in that it will help us control when our components re-render.
Basic Syntax
const wishMeComponent = React.memo(function MyComponent(props) {
// only renders if props have changed
});
This really helps us cut down re-renders but React.memo has a high initialization cost and requires some prop comparisons on each render. This, in moderation, is not an issue but the costs can add up to something significant.
useCallback
const memoizedCallback = useCallback(
() => {
doSomething(a, b);
},
[a, b],
);
According to the Official react website, useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
In the above example If a and b change every time usecallback need to generate a new reference for the function, this is an overhead as we need to compare previous and next value of a and b
So, in cases where a function will either not trigger a re-render or will always trigger a re-render (depends on all props) then, avoid wrapping your function with `useCallback`.
useMemo
The same ideas from `useCallback`, applies here. Memoization can have a small cost so using it in situations where dependencies change too frequently, it can hurt you more than you can justify.
So what do we learn from this?
The point of this post is definitely not that all of these features are bad in some way. The point is, don’t just blindly jump on every fast train you see. Take some time to understand how your tools work and how they can hurt you.
Develop. Measure. Optimize.
As Donald Knuth, famously said
“Premature optimization is the root of all evil”
References
https://reactjs.org
https://medium.com/@sgobinda007/using-reactjs-hoc-pattern-be-aware-of-the-side-effects-f52beae77703