Have you ever wondered how a child component in React can send data or trigger actions in its parent? 🤔
That exact concept — child-to-parent communication — is one of the most important patterns every React developer needs to understand.
Today, I’ll walk you through how I built a small app called “Listo 🛒”, where users can add, delete, and toggle packed items, all powered by React’s state and props magic ✨
⚙️ Step 1: The State Lives in the Parent
In React, state should live where it’s needed the most.
Since multiple child components (Form, PackingList, Stats) need to access the same list of items, I kept the state in the parent App component.
function App() {
const [items, setItems] = useState([]);
}
Now App becomes the single source of truth for the data.
🧾 Step 2: Adding an Item (Child → Parent)
To add a new item, I created a function in the parent that updates the state:
function handleAddItem(item) {
setItems((items) => [...items, item]);
}
Then I passed this function down to the Form component as a prop:
<Form onAddItem={handleAddItem} />
Inside the form, I created the new item and called the parent function:
function handleSubmit(e) {
e.preventDefault();
if (!description) return;
const newItem = {
description,
quantity,
unit,
packed: false,
id: Date.now(),
};
onAddItem(newItem);
}
💡 Concept:
When the form submits, it doesn’t change state itself — it calls a function from the parent, sending data upward. That’s child-to-parent communication in action!
🗑️ Step 3: Deleting an Item
For delete, the logic again stays in the parent:
function handleDeleteItem(id) {
setItems((items) => items.filter((item) => item.id !== id));
}
And we pass it down to each Item component through props:
<button onClick={() => onDeleteItem(item.id)}>❌</button>
When the button is clicked, the child triggers the parent’s delete logic — clean and simple.
✅ Step 4: Toggling “Packed” Status
This part flips the packed value between true and false using the item’s id.
function handleTogglePacked(id) {
setItems((items) =>
items.map((item) =>
item.id === id ? { ...item, packed: !item.packed } : item
)
);
}
Then inside each Item:
<input
type="checkbox"
checked={item.packed}
onChange={() => onTogglePacked(item.id)}
/>
Now, clicking the checkbox updates the parent state instantly.
✅ No complex logic, just pure React reactivity.
🧠 What I Learned
This small app might look simple, but it teaches some of the core principles of React:
- Keep state in the parent where multiple children can access it.
- Pass functions as props to let children communicate back.
- Always update state immutably (create new arrays/objects).
Once you understand this flow, everything in React — from forms to dashboards — becomes easier to reason about.
✨ Final Thoughts
Building “Listo 🛒” helped me finally connect theory with practice.
I used concepts like:
✅ Lifting state up
✅ Child-to-parent communication
✅ Controlled components
If you’re learning React, try this pattern in your own projects — it’ll solidify your understanding of how data flows in React. 💪
Top comments (0)