Hello everyone! If you're dealing with frequent data updates in your frontend development projects, especially from sources like backend servers or localStorage
, this article is essential for you. Discover how the keep-unchanged-values
library can enhance your React applications by optimizing data updates and minimizing performance issues. You need this if you're navigating through regular updates from various data sources.
Problem: Frequent data updates in large objects and lists cause performance issues
Solution: keep-unchanged-values
combined with React.memo
How it works:
Pass two entities to the keepUnchangedValues
function you want to "merge". The result is the second entity, and it will keep references to unchanged objects from the first entity:
const oldArray = [1, { a: 1 }, 3];
const newArray = [2, 3, 4, { a: 1 }];
// result is equal to [2, 3, 4, { a: 1 }]
const result = keepUnchangedValues(oldArray, newArray);
// logs true; result[3] will be a reference to oldArray[1] since they have the same link to the object
console.log(result[3] === oldArray[1])
Example:
Update data from external storage periodically
"Merge" new data with existing using
keepUnchangedValues
Update your state with "merged" data: the old nested objects will be the same, new data will be applied
import React, { useState, useEffect } from 'react';
import { keepUnchangedValues } from 'keep-unchanged-values';
const MyListComponent = () => {
const [list, setList] = useState([]);
useEffect(() => {
// Fetch data from API
const fetchHandler = () => {
fetchData().then(newItems => {
// Update the list with new items, maintaining unchanged ones
const updatedList = keepUnchangedValues(list, newItems);
// if nothing changed, returns the same list
setList(updatedList);
});
}
// Fetch initial data
fetchHandler()
// Set up polling
const intervalId = setInterval(fetchHandler, 5000); // Polling every 5 seconds
return () => clearInterval(intervalId);
}, [list]);
return (
<ul>
{list.map(item => <MemoizedListItem key={item.id} item={item} />)}
</ul>
);
};
const MemoizedListItem = React.memo(({ item }) => {
// Rerenders only if the current item changes.
// Works with shallow comparison because keepUnchangedValues maintains unchanged values
useEffect(() => {
somethingIneficient(item);
}, [item]);
return <li>{item.content}</li>;
});
export default MyListComponent;
Benefits:
Unchanged list items retain their references
React.memo
performs shallow comparisons and skips re-renders for unchanged items
Result? Smooth, efficient data updates!
Github: https://github.com/CascaSpace/keep-unchanged-values
Package: https://www.npmjs.com/package/keep-unchanged-values
More examples can be seen in the library tests https://github.com/CascaSpace/keep-unchanged-values/blob/main/src/index.test.js
If you want to learn more, check this article where we show how we optimized our Chrome Extension https://cascaspace.substack.com/p/optimizing-performance-how-our-extension
Top comments (0)