Module 5: State Management
Course Overview: This module teaches how to manage state in React Native applications. You will learn local state with React hooks, global state using Context API, Redux, and modern libraries like Recoil and Zustand. Handling asynchronous updates, middleware, and best practices for performance will also be covered.
✅ Local State with useState and useEffect
Local state is used within a component to manage dynamic data. React hooks like useState and useEffect make state management simple.
Example:
import React, { useState, useEffect } from 'react';
import { View, Text, Button } from 'react-native';
export default function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`Current count: ${count}`);
}, [count]);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={() => setCount(count + 1)} />
<Button title="Decrement" onPress={() => setCount(count - 1)} />
</View>
);
}
Key Points:
useState(initialValue)returns the current state and a setter function.useEffect()runs side-effects after render; can depend on specific state variables.- Local state is perfect for simple data within a component.
—
✅ Context API for Global State
Context API allows you to share state across multiple components without prop drilling.
Example:
import React, { createContext, useState, useContext } from 'react';
import { View, Text, Button } from 'react-native';
// Create a Context
const ThemeContext = createContext();
export default function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<View>
<Text>Current Theme: {theme}</Text>
<ThemeSwitcher />
</View>
</ThemeContext.Provider>
);
}
function ThemeSwitcher() {
const { theme, setTheme } = useContext(ThemeContext);
return (
<Button
title="Toggle Theme"
onPress={() => setTheme(theme === 'light' ? 'dark' : 'light')}
/>
);
}
Tips:
- Context is best for app-wide settings like themes, user authentication, or language preferences.
- Avoid overusing Context for frequently changing data; performance can degrade.
—
✅ Redux for Global State Management
Redux is a predictable state container for JavaScript apps. It centralizes the state and enforces a unidirectional data flow.
Install:
npm install redux react-redux redux-thunk
Example: Counter with Redux:
// actions.js
export const increment = () => ({ type: 'INCREMENT' });
export const decrement = () => ({ type: 'DECREMENT' });
// reducer.js
const initialState = { count: 0 };
export default function counterReducer(state = initialState, action) {
switch(action.type) {
case 'INCREMENT': return { count: state.count + 1 };
case 'DECREMENT': return { count: state.count - 1 };
default: return state;
}
}
// store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import counterReducer from './reducer';
export const store = createStore(counterReducer, applyMiddleware(thunk));
// App.js
import React from 'react';
import { Provider, useDispatch, useSelector } from 'react-redux';
import { View, Text, Button } from 'react-native';
import { store } from './store';
import { increment, decrement } from './actions';
function Counter() {
const count = useSelector(state => state.count);
const dispatch = useDispatch();
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={() => dispatch(increment())} />
<Button title="Decrement" onPress={() => dispatch(decrement())} />
</View>
);
}
export default function AppWrapper() {
return <Provider store={store}><Counter /></Provider>;
}
Tips:
- Redux Thunk allows asynchronous actions like API calls.
- Use Redux DevTools for debugging state changes.
- Keep actions and reducers organized for maintainability.
—
✅ Recoil and Zustand (Optional)
Modern libraries like Recoil and Zustand simplify global state management with less boilerplate than Redux.
Example: Zustand Counter:
import create from 'zustand';
const useStore = create(set => ({
count: 0,
increment: () => set(state => ({ count: state.count + 1 })),
decrement: () => set(state => ({ count: state.count - 1 }))
}));
export default function Counter() {
const { count, increment, decrement } = useStore();
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increment" onPress={increment} />
<Button title="Decrement" onPress={decrement} />
</View>
);
}
—
✅ Best Practices for State Management
- Keep local state in components and global state for app-wide data.
- Use Context API for small, simple global states.
- Use Redux or modern libraries for complex and frequently changing state.
- Always keep state immutable.
- Use middleware like Redux Thunk for async operations.
- Use DevTools and logging to track state changes and debug efficiently.
—
✅ Summary
Module 5 teaches different ways to manage state in React Native:
- Local state with React hooks (
useState,useEffect). - Global state with Context API.
- Redux for predictable state management and asynchronous actions.
- Modern libraries like Recoil and Zustand for simpler global state.
- Best practices include immutability, proper use of middleware, and debugging tools.
Mastering state management ensures your React Native apps are scalable, maintainable, and responsive.
