The Context API in React Native allows for global state management, but when dealing with complex state updates or performance optimizations, useCallback
and useMemo
become crucial. They help prevent unnecessary re-renders and optimize performance.
Why Use useCallback
and useMemo
?
πΉ useCallback
ensures functions donβt get re-created unnecessarily.
πΉ useMemo
prevents recalculations of derived state when dependencies haven't changed.
πΉ Both improve performance when passing values through Context.
1. Implementing Context API
Step 1: Create a Context
import React, { createContext, useState, useCallback, useMemo } from "react";
export const AppContext = createContext();
Step 2: Create a Provider with useCallback
and useMemo
const AppProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [theme, setTheme] = useState("light");
return (
<AppContext.Provider value={{ user, setUser, theme, setTheme }}>
{children}
</AppContext.Provider>
);
};
export default AppProvider;
or
const AppProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [theme, setTheme] = useState("light");
// useCallback to prevent function recreation
const toggleTheme = useCallback(() => {
setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
}, []);
const loginUser = useCallback(() => {
setUser("John Doe");
}, []);
// useMemo to optimize the value object
const contextValue = useMemo(() => ({
user,
theme,
toggleTheme,
loginUser,
}), [user, theme, toggleTheme, loginUser]);
return (
<AppContext.Provider value={contextValue}>
{children}
</AppContext.Provider>
);
};
export default AppProvider;
Optimizations:
-
toggleTheme
andloginUser
useuseCallback
to avoid unnecessary re-creations. -
contextValue
usesuseMemo
to ensure it only changes when dependencies update.
Step 3: Wrap the App with the Provider
import React from "react";
import { View, Text } from "react-native";
import AppProvider from "./AppProvider";
import HomeScreen from "./HomeScreen";
const App = () => {
return (
<AppProvider>
<HomeScreen />
</AppProvider>
);
};
export default App;
Step 4: Consume Context in a Component
import React, { useContext } from "react";
import { View, Text, Button } from "react-native";
import { AppContext } from "./AppProvider";
const HomeScreen = () => {
const { user, theme, toggleTheme, loginUser } = useContext(AppContext);
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Current User: {user || "Guest"}</Text>
<Text>Theme: {theme}</Text>
<Button title="Login" onPress={loginUser} />
<Button title="Toggle Theme" onPress={toggleTheme} />
</View>
);
};
export default HomeScreen;
Why This is Optimized?
π Prevents unnecessary re-renders when passing functions (useCallback
).
π Prevents unnecessary re-creation of objects (useMemo
).
π Improves performance when using Context API in larger apps.
When to Use useCallback
and useMemo
?
β
Use useCallback
when passing functions to child components to prevent re-creation.
β
Use useMemo
when computing derived values that are expensive to recalculate.
When to Use Context API in React Native?
β
When managing global state (authentication, themes, language preferences).
β
When passing data deeply into the component tree.
β
When you need a simple state management solution.
β Avoid using it for frequently changing state (like animations or high-frequency updates).
β Not ideal for complex state management (consider Redux/Zustand in such cases).
Final Thoughts
- Context API is great for global state, and adding
useCallback
anduseMemo
optimizes it. - For complex state management, consider Redux, Zustand, or Recoil for better scalability.
Top comments (0)