Performance Tuning in React Native: How to Use useMemo and useCallback
In React Native, useMemo
and useCallback
are hooks used for performance optimization.
They helps to avoid unnecessary re-renders by memoizing values and functions.
Here are some use cases for each:
useMemo
useMemo
is used to memoize the result of a calculation or an expensive operation, ensuring it is only re-calculated when its dependencies will be change.
Filtering and Sorting: When filtering or sorting large datasets, you can use useMemo
to memoize the result to avoid recalculating it on every render.
import React, { useMemo } from 'react';
import { View, Text } from 'react-native';
const ItemList = ({ items }) => {
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.name.localeCompare(b.name));
}, [items]);
return (
<View>
{sortedItems.map(item => (
<Text key={item.id}>{item.name}</Text>
))}
</View>
);
};
export default ItemList;
useCallback
useCallback
is used to memoize callback functions, preventing them from being recreated on every render unless their dependencies change.
This is useful for passing stable references to child components and optimizing performance.
Event Handlers: When you have event handlers that are passed down to child components, you can use useCallback
to ensure they are not recreated on every render, which can help avoid unnecessary re-renders of the child components.
Event handlers such as “button click event, text change event and switch the on an off event’
import React, { useState, useCallback } from 'react';
import { View, Button, Text } from 'react-native';
const ParentComponent = () => {
const [count, setCount] = useState(0);
const increment = useCallback(() => {
setCount(prevCount => prevCount + 1);
}, []);
return (
<View>
<Text>Count: {count}</Text>
<ChildComponent onClick={increment} />
</View>
);
};
export default ParentComponent;
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent rendered');
return <Button title="Click me" onPress={onClick} />;
});
Optimizing Props for Memoized Components:
When using React.memo
to memoize components, useCallback
can help ensure that props (especially functions) do not cause unnecessary re-renders.
import React, { useState, useCallback } from 'react';
import { View, Button, Text } from 'react-native';
const ExpensiveComponent = React.memo(({ fetchData }) => {
console.log('ExpensiveComponent rendered');
return (
<View>
<Button title="Fetch Data" onPress={fetchData} />
</View>
);
});
const ParentComponent = () => {
const [data, setData] = useState(null);
const fetchData = useCallback(() => {
// Simulate fetching data
setData({ name: 'Test' });
}, []);
return (
<View>
<ExpensiveComponent fetchData={fetchData} />
{data && <Text>Data: {data.name}</Text>}
</View>
);
};
export default ParentComponent;
Summary
- useMemo: Use for memoizing expensive calculations or operations to avoid recalculations on every render.
- useCallback: Use for memoizing functions, especially event handlers, to prevent unnecessary re-renders of child components.
By strategically using useMemo
and useCallback
, you can significantly improve the performance of your React Native applications, ensuring that components only re-render when necessary.