Example A
function NavBar() {
const { products } = React.useContext(StoreContext);
return (
<nav style={{ display: 'flex', gap: '1rem' }}>
<a>Home</a>
<a>
Basket<span style={{ marginLeft: '0.5rem' }}>{products.length}</span>
</a>
</nav>
);
}
Example B
function NavBar2() {
const { products } = React.useContext(StoreContext);
return (
<nav style={{ display: 'flex', gap: '1rem' }}>
<a>Home</a>
<a>
Basket
<ProductCount />
</a>
</nav>
);
}
function ProductCount() {
const { products } = React.useContext(StoreContext);
return <span style={{ marginLeft: '0.5rem' }}>{products.length}</span>;
}
Consider NavBar
is some big component which could deal with UserProfile
details and much. Out of the two examples which will be more performant? Does creating a small component like ProductCount
be fruitful or an unnecessary overhead for react to create and maintain another component?
I thought if I put the useContext
close to where I use the value, I could avoid unnecessary rendering of component which doesn’t directly linked to the value (here NavBar
). For example If products gets updated, In example A whole NavBar
will be re-rendered which could be a big component but in Example B, only ProductCount
is re-rendered
2
Answers
There isn’t enough information to say which would be more performant, but it’s unlikely either would have a noticeable impact from a user perspective.
How you retrieve and store data to be displayed is where your performance gaps will likely be waiting. In this example, variables like how many products you need to retrieve from your server, the quality of their images, if pricing is dynamic, etc. are more likely to impact performance.
Some best practices to maximize performance as you scale would include:
Thinking-in-React from the docs is a great resource to better understand how to break up your UI into components as well.
You can further improve performance by structuring your app to reuse components efficiently. I’ve included an example of how you might structure a shopping cart below.
Create two new files, first one called CartLineItem.jsx like below.
And the second file called OrderSummary.jsx, where you display all of the cart’s line items for review. We’re passing this component an itemArray which could be updated using the Reducer hook and shared with the useContext hook.
The above is very high-level and just one example of how you might structure a React app for performance. There are many, many, different ways to improve performance using React but most are dependent on your specific use case.
Hopefully the above gives you some new insight into how you might structure your React app to maximize performance and reduce your dev time.
Good luck with your journey!
The rule of thumb I tell my developers to use is similar to the react documentation about keeping higher-order components as pure as possible while maximizing readability in their containers.
For your example, you are extracting ProductCount, if this is a component that performs a very specific function then it can be extracted. Another reason could be reuse, if you are writing the same lines of code over and over then odds are you should make a reusable component for this.
When creating reusable components you should also try to make them as ambiguous as possible and non-dependent.
When it comes to performance it is not very likely that extracting components will improve performance because performance is all based on how the code is designed. Extracted vs not extracted will be the same if the design is the same because of how the code gets compiled and built.
Tha main purpose of doing what you mentioned is to improve readability, stop repeating code/create reusable components, and for easier error handling and testing but performance is all on the code itself and how it is designed which can be easily seen in the example you provided, performance is the same but if there was an issue within the extracted component it would be easier to diagnose and solve a small component vs a large one.