Chapter 12: React Hooks, Side Effects & Data Flow
Recommended New Learning Flow
- Why Hooks?
- useState refresher
- Managing Expense List
- Updating State Correctly
- useEffect introduction
- Dependency arrays
- Derived values (totals)
- Fetching/loading data
- Cleanup functions
- Rules of Hooks
- Custom hooks
- One-way data flow
- Parent-child communication
- Common mistakes
- Best practices
- Exercises
Important Improvements You Should Add
1. Add “Why Hooks?” Section
Before directly starting useState.
# Why React Hooks?
Before Hooks, React developers mainly used Class Components for managing state and lifecycle methods.
Hooks allow Functional Components to:
- Manage state
- Handle side effects
- Share reusable logic
- Write cleaner and smaller code
Hooks made React development simpler and more powerful.
In modern React Native applications, Hooks are the standard approach.
2. Align useState Example with ExpenseApp
Instead of generic counter example first, start directly with ExpenseApp context.
Replace this:
const [count, setCount] = useState(0);
With:
const [description, setDescription] = useState("");
const [amount, setAmount] = useState("");
Because previous chapters already established this flow.
Then later introduce counter as secondary example if needed.
3. Add Proper TypeScript Types
Current examples miss TypeScript typing consistency.
Add:
type Expense = {
id: number;
description: string;
amount: number;
};
Then:
const [expenses, setExpenses] = useState<Expense[]>([]);
This aligns with earlier chapters.
4. Improve State Update Example
Current:
setExpenses([...expenses, expense]);
Better teaching version:
setExpenses((prevExpenses) => [...prevExpenses, newExpense]);
Then explain WHY:
👉 Functional updates always use the latest state
👉 Prevents stale state issues
👉 Recommended when new state depends on previous state
5. Add Full ExpenseApp Example
This is missing currently.
You should add a complete working example like this:
import React, { useState } from "react";
import { SafeAreaView, Text, TextInput, Pressable, View } from "react-native";
type Expense = {
id: number;
description: string;
amount: number;
};
export default function App() {
const [description, setDescription] = useState("");
const [amount, setAmount] = useState("");
const [expenses, setExpenses] = useState<Expense[]>([]);
const handleAddExpense = () => {
const newExpense = {
id: Date.now(),
description,
amount: Number(amount),
};
setExpenses((prevExpenses) => [...prevExpenses, newExpense]);
setDescription("");
setAmount("");
};
return (
<SafeAreaView>
<TextInput
value={description}
onChangeText={setDescription}
placeholder="Description"
/>
<TextInput
value={amount}
onChangeText={setAmount}
placeholder="Amount"
keyboardType="numeric"
/>
<Pressable onPress={handleAddExpense}>
<Text>Add Expense</Text>
</Pressable>
{expenses.map((item) => (
<View key={item.id}>
<Text>{item.description}</Text>
<Text>₹{item.amount}</Text>
</View>
))}
</SafeAreaView>
);
}
This keeps continuity with earlier chapters.
6. Add “Derived State” Explanation
Very important educational concept.
# Derived State
Sometimes values are calculated from existing state instead of stored separately.
Example:
- Total expense amount
- Expense count
- Average expense
These values are called derived state.
Then show:
const totalAmount = expenses.reduce((sum, item) => sum + item.amount, 0);
Then explain:
👉 Avoid storing derived values separately unless necessary
👉 Reduces bugs and duplicate state
This is a VERY important React concept.
7. Improve useEffect Section
Current explanation is too short.
Add lifecycle explanation:
useEffect replaces lifecycle methods from Class Components:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
8. Add Loading State Example
Excellent real-world concept.
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchExpenses = async () => {
setLoading(true);
const data = [
{
id: 1,
description: "Food",
amount: 250,
},
];
setExpenses(data);
setLoading(false);
};
fetchExpenses();
}, []);
Then:
if (loading) {
return <Text>Loading expenses...</Text>;
}
Very practical.
9. Add “Rules of Hooks”
Very important and currently missing.
# Rules of Hooks
Hooks must:
✅ Be called at the top level
✅ Be called inside React components
✅ Be called in same order every render
Hooks should NOT:
❌ Be called inside loops
❌ Be called inside conditions
❌ Be called inside nested functions
10. Improve Custom Hook Example
Current custom hook is too simple.
Better:
📁 src/hooks/useExpenses.ts
import { useState } from "react";
type Expense = {
id: number;
description: string;
amount: number;
};
export default function useExpenses() {
const [expenses, setExpenses] = useState<Expense[]>([]);
const addExpense = (description: string, amount: number) => {
const newExpense = {
id: Date.now(),
description,
amount,
};
setExpenses((prev) => [...prev, newExpense]);
};
const totalAmount = expenses.reduce((sum, item) => sum + item.amount, 0);
return {
expenses,
addExpense,
totalAmount,
};
}
This demonstrates reusable business logic properly.
11. Add Parent → Child → Parent Communication
Current chapter only shows downward flow.
Add callback props:
function Parent() {
const handleSave = () => {
console.log("Saved");
};
return <Child onSave={handleSave} />;
}
function Child({ onSave }) {
return (
<Pressable onPress={onSave}>
<Text>Save</Text>
</Pressable>
);
}
Then explain:
👉 Data flows downward
👉 Events flow upward through callback functions
Very important architecture concept.
12. Add Common useEffect Mistakes
This section will help beginners a LOT.
# Common useEffect Mistakes
❌ Missing dependency array
→ Causes unnecessary re-renders
❌ Updating state inside effect incorrectly
→ May create infinite loops
❌ Putting every variable in dependency array blindly
→ Can cause unexpected executions
Then show bad example:
useEffect(() => {
setCount(count + 1);
}, [count]);
Explain infinite loop clearly.
13. Add Folder Structure
src/
├── app/
│ └── index.tsx
├── components/
│ └── ExpenseItem.tsx
├── hooks/
│ └── useExpenses.ts
└── styles/
└── styles.ts
Improves beginner clarity.
14. Add Practice Exercises
Very valuable for training workshops.
# Practice Exercises
1. Add Delete Expense functionality
2. Show total expense count
3. Add loading indicator
4. Create custom hook for totals
5. Add category field
6. Show highest expense
15. Improve Final Summary
Current summary is too short.
Recommended:
# Chapter Summary
In this chapter, you:
✅ Learned why Hooks are important
✅ Used `useState` for dynamic UI
✅ Managed arrays and objects in state
✅ Understood immutable updates
✅ Learned `useEffect` and side effects
✅ Used dependency arrays correctly
✅ Calculated derived values
✅ Learned cleanup functions
✅ Created reusable custom hooks
✅ Understood one-way data flow
✅ Passed callbacks between components
✅ Followed React Hook best practices