Master state management patterns and libraries for React Native applications.
Master state management patterns and libraries for React Native applications.
Learn to use React hooks for local state management and side effects in React Native applications
Content by: Ronak Macwan
React Native Developer
useState is the most basic hook for managing local state in functional components. It returns a stateful value and a function to update it, triggering a re-render when the state changes.
useEffect lets you perform side effects in functional components. It's similar to componentDidMount, componentDidUpdate, and componentWillUnmount combined in class components.
import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Alert } from 'react-native';
const CounterApp = () => {
const [count, setCount] = useState(0);
const [isEven, setIsEven] = useState(true);
// Effect to check if count is even
useEffect(() => {
setIsEven(count % 2 === 0);
}, [count]);
// Effect to show alert when count reaches 10
useEffect(() => {
if (count === 10) {
Alert.alert('Congratulations!', 'You reached 10!');
}
}, [count]);
const increment = () => {
setCount(prevCount => prevCount + 1);
};
const decrement = () => {
setCount(prevCount => prevCount - 1);
};
const reset = () => {
setCount(0);
};
return (
<View style={styles.container}>
<Text style={styles.title}>Counter App</Text>
<View style={styles.counterContainer}>
<Text style={styles.count}>{count}</Text>
<Text style={[styles.status, isEven ? styles.even : styles.odd]}>
{isEven ? 'Even' : 'Odd'}
</Text>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={decrement}>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={increment}>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.resetButton} onPress={reset}>
<Text style={styles.resetButtonText}>Reset</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 30,
color: '#333',
},
counterContainer: {
alignItems: 'center',
marginBottom: 30,
},
count: {
fontSize: 48,
fontWeight: 'bold',
color: '#2196F3',
marginBottom: 10,
},
status: {
fontSize: 18,
fontWeight: '500',
},
even: {
color: '#4CAF50',
},
odd: {
color: '#FF9800',
},
buttonContainer: {
flexDirection: 'row',
marginBottom: 20,
},
button: {
backgroundColor: '#2196F3',
width: 60,
height: 60,
borderRadius: 30,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 10,
},
buttonText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold',
},
resetButton: {
backgroundColor: '#f44336',
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 8,
},
resetButtonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});
export default CounterApp;Test your understanding of this topic:
Learn to use React Context API for sharing state across multiple components without prop drilling in React Native applications
Content by: Ronak Macwan
React Native Developer
Context provides a way to pass data through the component tree without having to pass props down manually at every level. It's perfect for sharing global state like user authentication, theme, or language preferences.
Use React.createContext() to create a context object. The context object contains a Provider component that allows consuming components to subscribe to context changes.
The Provider component accepts a value prop that is passed to all consuming components. When the value changes, all consuming components will re-render.
Components can consume context using the useContext hook or the Consumer component. The useContext hook is the recommended way in functional components.
import React, { createContext, useContext, useState, useEffect } from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Alert } from 'react-native';
// Create Theme Context
const ThemeContext = createContext();
// Theme Provider Component
const ThemeProvider = ({ children }) => {
const [isDarkMode, setIsDarkMode] = useState(false);
const [user, setUser] = useState(null);
const toggleTheme = () => {
setIsDarkMode(prev => !prev);
};
const login = (userData) => {
setUser(userData);
};
const logout = () => {
setUser(null);
};
const theme = {
isDarkMode,
colors: isDarkMode ? {
background: '#1a1a1a',
text: '#ffffff',
primary: '#bb86fc',
surface: '#2d2d2d',
} : {
background: '#ffffff',
text: '#000000',
primary: '#2196F3',
surface: '#f5f5f5',
},
toggleTheme,
user,
login,
logout,
};
return (
<ThemeContext.Provider value={theme}>
{children}
</ThemeContext.Provider>
);
};
// Custom hook to use theme
const useTheme = () => {
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme must be used within a ThemeProvider');
}
return context;
};
// Header Component
const Header = () => {
const { isDarkMode, toggleTheme, user } = useTheme();
return (
<View style={[styles.header, { backgroundColor: isDarkMode ? '#2d2d2d' : '#2196F3' }]}>
<Text style={[styles.headerTitle, { color: 'white' }]}>
{user ? `Welcome, ${user.name}!` : 'My App'}
</Text>
<TouchableOpacity onPress={toggleTheme} style={styles.themeButton}>
<Text style={styles.themeButtonText}>
{isDarkMode ? 'āļø' : 'š'}
</Text>
</TouchableOpacity>
</View>
);
};
// Main Content Component
const MainContent = () => {
const { colors, user, login, logout } = useTheme();
const handleLogin = () => {
login({ name: 'John Doe', email: 'john@example.com' });
};
const handleLogout = () => {
logout();
};
return (
<View style={[styles.container, { backgroundColor: colors.background }]}>
<Text style={[styles.title, { color: colors.text }]}>
Theme Context Example
</Text>
<View style={[styles.card, { backgroundColor: colors.surface }]}>
<Text style={[styles.cardTitle, { color: colors.text }]}>
Current Theme
</Text>
<Text style={[styles.cardText, { color: colors.text }]}>
{colors.background === '#1a1a1a' ? 'Dark Mode' : 'Light Mode'}
</Text>
</View>
<View style={styles.buttonContainer}>
{user ? (
<TouchableOpacity
style={[styles.button, { backgroundColor: '#f44336' }]}
onPress={handleLogout}
>
<Text style={styles.buttonText}>Logout</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={[styles.button, { backgroundColor: colors.primary }]}
onPress={handleLogin}
>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
)}
</View>
</View>
);
};
// Main App Component
const App = () => {
return (
<ThemeProvider>
<View style={styles.app}>
<Header />
<MainContent />
</View>
</ThemeProvider>
);
};
const styles = StyleSheet.create({
app: {
flex: 1,
},
header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 20,
paddingTop: 40,
},
headerTitle: {
fontSize: 20,
fontWeight: 'bold',
},
themeButton: {
padding: 10,
},
themeButtonText: {
fontSize: 20,
},
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 30,
},
card: {
padding: 20,
borderRadius: 8,
marginBottom: 30,
},
cardTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
cardText: {
fontSize: 16,
},
buttonContainer: {
alignItems: 'center',
},
button: {
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 8,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});
export default App;Test your understanding of this topic:
Learn to implement Redux Toolkit for complex state management in React Native applications with modern Redux patterns
Content by: Ronak Macwan
React Native Developer
Redux Toolkit (RTK) is the official, opinionated, batteries-included toolset for efficient Redux development. It simplifies Redux setup and reduces boilerplate code significantly.
Install Redux Toolkit and React Redux: `npm install @reduxjs/toolkit react-redux`. For React Native, you might also need `react-redux` with proper setup.
import React from 'react';
import { Provider, useSelector, useDispatch } from 'react-redux';
import { configureStore, createSlice } from '@reduxjs/toolkit';
import { View, Text, TouchableOpacity, StyleSheet, FlatList } from 'react-native';
// Counter Slice
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
history: [],
},
reducers: {
increment: (state) => {
state.value += 1;
state.history.push({ action: 'increment', timestamp: Date.now() });
},
decrement: (state) => {
state.value -= 1;
state.history.push({ action: 'decrement', timestamp: Date.now() });
},
reset: (state) => {
state.value = 0;
state.history.push({ action: 'reset', timestamp: Date.now() });
},
clearHistory: (state) => {
state.history = [];
},
},
});
// Todo Slice
const todoSlice = createSlice({
name: 'todos',
initialState: {
items: [],
filter: 'all', // all, active, completed
},
reducers: {
addTodo: (state, action) => {
const newTodo = {
id: Date.now(),
text: action.payload,
completed: false,
createdAt: Date.now(),
};
state.items.push(newTodo);
},
toggleTodo: (state, action) => {
const todo = state.items.find(item => item.id === action.payload);
if (todo) {
todo.completed = !todo.completed;
}
},
deleteTodo: (state, action) => {
state.items = state.items.filter(item => item.id !== action.payload);
},
setFilter: (state, action) => {
state.filter = action.payload;
},
},
});
// Configure Store
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
todos: todoSlice.reducer,
},
});
// Export actions
export const { increment, decrement, reset, clearHistory } = counterSlice.actions;
export const { addTodo, toggleTodo, deleteTodo, setFilter } = todoSlice.actions;
// Counter Component
const Counter = () => {
const count = useSelector(state => state.counter.value);
const history = useSelector(state => state.counter.history);
const dispatch = useDispatch();
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Counter: {count}</Text>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.button}
onPress={() => dispatch(increment())}
>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => dispatch(decrement())}
>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, styles.resetButton]}
onPress={() => dispatch(reset())}
>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
</View>
<Text style={styles.historyTitle}>History ({history.length})</Text>
<FlatList
data={history.slice(-5).reverse()}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<Text style={styles.historyItem}>
{item.action} at {new Date(item.timestamp).toLocaleTimeString()}
</Text>
)}
style={styles.historyList}
/>
{history.length > 0 && (
<TouchableOpacity
style={styles.clearButton}
onPress={() => dispatch(clearHistory())}
>
<Text style={styles.clearButtonText}>Clear History</Text>
</TouchableOpacity>
)}
</View>
);
};
// Todo Component
const TodoApp = () => {
const todos = useSelector(state => state.todos.items);
const filter = useSelector(state => state.todos.filter);
const dispatch = useDispatch();
const filteredTodos = todos.filter(todo => {
if (filter === 'active') return !todo.completed;
if (filter === 'completed') return todo.completed;
return true;
});
const addNewTodo = () => {
const text = `Todo ${todos.length + 1}`;
dispatch(addTodo(text));
};
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Todo App</Text>
<View style={styles.filterContainer}>
<TouchableOpacity
style={[styles.filterButton, filter === 'all' && styles.activeFilter]}
onPress={() => dispatch(setFilter('all'))}
>
<Text style={styles.filterText}>All</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.filterButton, filter === 'active' && styles.activeFilter]}
onPress={() => dispatch(setFilter('active'))}
>
<Text style={styles.filterText}>Active</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.filterButton, filter === 'completed' && styles.activeFilter]}
onPress={() => dispatch(setFilter('completed'))}
>
<Text style={styles.filterText}>Completed</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.addButton} onPress={addNewTodo}>
<Text style={styles.addButtonText}>Add Todo</Text>
</TouchableOpacity>
<FlatList
data={filteredTodos}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.todoItem}>
<TouchableOpacity
style={styles.todoText}
onPress={() => dispatch(toggleTodo(item.id))}
>
<Text style={[
styles.todoTextContent,
item.completed && styles.completedTodo
]}>
{item.text}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.deleteButton}
onPress={() => dispatch(deleteTodo(item.id))}
>
<Text style={styles.deleteButtonText}>Ć</Text>
</TouchableOpacity>
</View>
)}
style={styles.todoList}
/>
</View>
);
};
// Main App
const App = () => {
return (
<Provider store={store}>
<View style={styles.container}>
<Text style={styles.title}>Redux Toolkit Example</Text>
<Counter />
<TodoApp />
</View>
</Provider>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 30,
color: '#333',
},
section: {
marginBottom: 30,
backgroundColor: 'white',
padding: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
sectionTitle: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 15,
color: '#333',
},
buttonContainer: {
flexDirection: 'row',
marginBottom: 15,
},
button: {
backgroundColor: '#2196F3',
padding: 10,
marginHorizontal: 5,
borderRadius: 5,
minWidth: 50,
alignItems: 'center',
},
resetButton: {
backgroundColor: '#f44336',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
historyTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 10,
color: '#333',
},
historyList: {
maxHeight: 100,
},
historyItem: {
fontSize: 12,
color: '#666',
marginBottom: 2,
},
clearButton: {
backgroundColor: '#ff9800',
padding: 8,
borderRadius: 5,
alignItems: 'center',
marginTop: 10,
},
clearButtonText: {
color: 'white',
fontSize: 12,
fontWeight: 'bold',
},
filterContainer: {
flexDirection: 'row',
marginBottom: 15,
},
filterButton: {
padding: 8,
marginRight: 10,
borderRadius: 5,
backgroundColor: '#e0e0e0',
},
activeFilter: {
backgroundColor: '#2196F3',
},
filterText: {
fontSize: 14,
color: '#333',
},
addButton: {
backgroundColor: '#4CAF50',
padding: 10,
borderRadius: 5,
alignItems: 'center',
marginBottom: 15,
},
addButtonText: {
color: 'white',
fontWeight: 'bold',
},
todoList: {
maxHeight: 200,
},
todoItem: {
flexDirection: 'row',
alignItems: 'center',
padding: 10,
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
todoText: {
flex: 1,
},
todoTextContent: {
fontSize: 16,
color: '#333',
},
completedTodo: {
textDecorationLine: 'line-through',
color: '#999',
},
deleteButton: {
backgroundColor: '#f44336',
width: 30,
height: 30,
borderRadius: 15,
alignItems: 'center',
justifyContent: 'center',
},
deleteButtonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
});
export default App;Test your understanding of this topic:
Learn to use Zustand, a lightweight state management library that provides a simple and intuitive API for managing state in React Native applications
Content by: Ronak Macwan
React Native Developer
Zustand is a small, fast, and scalable state management solution. It has a minimal API and doesn't require providers or complex setup, making it perfect for React Native applications.
Install Zustand: `npm install zustand`. For React Native, you might also want to install `zustand/middleware` for additional features.
import React from 'react';
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { View, Text, TouchableOpacity, StyleSheet, TextInput, FlatList } from 'react-native';
// Counter Store
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// Todo Store with Persistence
const useTodoStore = create(
persist(
(set, get) => ({
todos: [],
filter: 'all',
addTodo: (text) => set((state) => ({
todos: [...state.todos, {
id: Date.now(),
text,
completed: false,
createdAt: Date.now(),
}]
})),
toggleTodo: (id) => set((state) => ({
todos: state.todos.map(todo =>
todo.id === id ? { ...todo, completed: !todo.completed } : todo
)
})),
deleteTodo: (id) => set((state) => ({
todos: state.todos.filter(todo => todo.id !== id)
})),
setFilter: (filter) => set({ filter }),
clearCompleted: () => set((state) => ({
todos: state.todos.filter(todo => !todo.completed)
})),
getFilteredTodos: () => {
const { todos, filter } = get();
switch (filter) {
case 'active':
return todos.filter(todo => !todo.completed);
case 'completed':
return todos.filter(todo => todo.completed);
default:
return todos;
}
},
}),
{
name: 'todo-storage',
storage: createJSONStorage(() => AsyncStorage),
}
)
);
// Counter Component
const Counter = () => {
const { count, increment, decrement, reset } = useCounterStore();
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Counter: {count}</Text>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={decrement}>
<Text style={styles.buttonText}>-</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={increment}>
<Text style={styles.buttonText}>+</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.resetButton]} onPress={reset}>
<Text style={styles.buttonText}>Reset</Text>
</TouchableOpacity>
</View>
</View>
);
};
// Todo Component
const TodoApp = () => {
const {
todos,
filter,
addTodo,
toggleTodo,
deleteTodo,
setFilter,
clearCompleted,
getFilteredTodos,
} = useTodoStore();
const [newTodoText, setNewTodoText] = React.useState('');
const handleAddTodo = () => {
if (newTodoText.trim()) {
addTodo(newTodoText.trim());
setNewTodoText('');
}
};
const filteredTodos = getFilteredTodos();
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Todo App (Persistent)</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.textInput}
value={newTodoText}
onChangeText={setNewTodoText}
placeholder="Add a new todo..."
onSubmitEditing={handleAddTodo}
/>
<TouchableOpacity style={styles.addButton} onPress={handleAddTodo}>
<Text style={styles.addButtonText}>Add</Text>
</TouchableOpacity>
</View>
<View style={styles.filterContainer}>
<TouchableOpacity
style={[styles.filterButton, filter === 'all' && styles.activeFilter]}
onPress={() => setFilter('all')}
>
<Text style={styles.filterText}>All ({todos.length})</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.filterButton, filter === 'active' && styles.activeFilter]}
onPress={() => setFilter('active')}
>
<Text style={styles.filterText}>Active ({todos.filter(t => !t.completed).length})</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.filterButton, filter === 'completed' && styles.activeFilter]}
onPress={() => setFilter('completed')}
>
<Text style={styles.filterText}>Completed ({todos.filter(t => t.completed).length})</Text>
</TouchableOpacity>
</View>
{todos.some(todo => todo.completed) && (
<TouchableOpacity style={styles.clearButton} onPress={clearCompleted}>
<Text style={styles.clearButtonText}>Clear Completed</Text>
</TouchableOpacity>
)}
<FlatList
data={filteredTodos}
keyExtractor={item => item.id.toString()}
renderItem={({ item }) => (
<View style={styles.todoItem}>
<TouchableOpacity
style={styles.todoText}
onPress={() => toggleTodo(item.id)}
>
<Text style={[
styles.todoTextContent,
item.completed && styles.completedTodo
]}>
{item.text}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.deleteButton}
onPress={() => deleteTodo(item.id)}
>
<Text style={styles.deleteButtonText}>Ć</Text>
</TouchableOpacity>
</View>
)}
style={styles.todoList}
ListEmptyComponent={
<Text style={styles.emptyText}>
{filter === 'all' ? 'No todos yet' :
filter === 'active' ? 'No active todos' :
'No completed todos'}
</Text>
}
/>
</View>
);
};
// Main App
const App = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Zustand State Management</Text>
<Counter />
<TodoApp />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 30,
color: '#333',
},
section: {
marginBottom: 30,
backgroundColor: 'white',
padding: 20,
borderRadius: 8,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
sectionTitle: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 15,
color: '#333',
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'center',
},
button: {
backgroundColor: '#2196F3',
padding: 10,
marginHorizontal: 5,
borderRadius: 5,
minWidth: 50,
alignItems: 'center',
},
resetButton: {
backgroundColor: '#f44336',
},
buttonText: {
color: 'white',
fontWeight: 'bold',
},
inputContainer: {
flexDirection: 'row',
marginBottom: 15,
},
textInput: {
flex: 1,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 5,
padding: 10,
marginRight: 10,
fontSize: 16,
},
addButton: {
backgroundColor: '#4CAF50',
padding: 10,
borderRadius: 5,
alignItems: 'center',
justifyContent: 'center',
},
addButtonText: {
color: 'white',
fontWeight: 'bold',
},
filterContainer: {
flexDirection: 'row',
marginBottom: 15,
},
filterButton: {
padding: 8,
marginRight: 10,
borderRadius: 5,
backgroundColor: '#e0e0e0',
},
activeFilter: {
backgroundColor: '#2196F3',
},
filterText: {
fontSize: 12,
color: '#333',
},
clearButton: {
backgroundColor: '#ff9800',
padding: 8,
borderRadius: 5,
alignItems: 'center',
marginBottom: 15,
},
clearButtonText: {
color: 'white',
fontSize: 12,
fontWeight: 'bold',
},
todoList: {
maxHeight: 200,
},
todoItem: {
flexDirection: 'row',
alignItems: 'center',
padding: 10,
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
todoText: {
flex: 1,
},
todoTextContent: {
fontSize: 16,
color: '#333',
},
completedTodo: {
textDecorationLine: 'line-through',
color: '#999',
},
deleteButton: {
backgroundColor: '#f44336',
width: 30,
height: 30,
borderRadius: 15,
alignItems: 'center',
justifyContent: 'center',
},
deleteButtonText: {
color: 'white',
fontSize: 18,
fontWeight: 'bold',
},
emptyText: {
textAlign: 'center',
color: '#999',
fontStyle: 'italic',
marginTop: 20,
},
});
export default App;Test your understanding of this topic:
Continue your learning journey and master the next set of concepts.
Continue to Module 6