Study notes
Place shared state at the nearest common owner.
Read the explanation, run the worked example, then complete the matching Examples and Assignments tabs. Your original materials remain available alongside these notes.
Understand the idea
Refactoring should preserve behavior while splitting responsibilities. In your todo project, the parent owns tasks, the form reports a new title, and each row reports toggle or delete. In the ecommerce cart, the catalog reports a product and the cart reports a quantity change.
Prop drilling means passing a value through intermediate components. It is often a clear design for a short tree. If many distant components need the same data, context may simplify delivery, but it does not decide ownership for you. Keep a single authoritative cart and derive counts and totals from it.
Run the example
Use a separate React practice project with a Node.js version supported by Vite. Create it once with these commands, then use its development URL. Do not paste this into the Edupoly website’s own source files.
npm create vite@latest react-practice -- --template react
cd react-practice
npm install
npm run dev
Replace src/App.jsx with the following complete example. Keep Vite’s generated src/main.jsx entry point.
src/App.jsx
import { useState } from 'react';
function Product({onAdd}) { return <button onClick={() => onAdd({id: 'book', name: 'Book', price: 100})}>Add book</button>; }
function Cart({items, onRemove}) { return <ul>{items.map(item => <li key={item.id}>{item.name}: {item.quantity}<button onClick={() => onRemove(item.id)}>Remove</button></li>)}</ul>; }
export default function App() {
const [items, setItems] = useState([]);
function add(product) {
setItems(old => old.some(p => p.id === product.id)
? old.map(p => p.id === product.id ? {...p, quantity: p.quantity + 1} : p)
: [...old, {...product, quantity: 1}]);
}
return <main><Product onAdd={add} /><Cart items={items} onRemove={id => setItems(old => old.filter(p => p.id !== id))} /><p>Total: ₹{items.reduce((sum, p) => sum + p.price * p.quantity, 0)}</p></main>;
}
Expected result
Two Add book clicks produce one cart row with quantity 2 and total ₹200; Remove empties the cart.
Apply this to your assignments
Refactor your existing todo and cart apps one component at a time. Add quantity decrement with a defined zero rule, then test that counts, prices and row removal remain consistent.
Your existing examples
- Refactoring-child-parent-comm-project-todolist
- Parent-child-comm-project-ecom-cart
Open the Examples tab to run or inspect these supplied projects. Their original links are preserved.
Open Assignments for your complete original worksheet and submission controls.
Common mistakes
Duplicating cart state in siblings causes disagreement. Avoid storing a total that can be computed from items.
Check your understanding
- Predict the output before running the example, then compare it with the result panel.
- Explain which value each expression reads and which action changes it.
- Try the boundary cases listed in the practice task and record what you observe.
- Rebuild one matching assignment without copying, then compare behavior with the original example.
Reference
Official documentation for this topic · Vite setup requirements
