import { useState } from 'react';
const initialPlan = {
0: { id: 0, title: '(Root)', childIds: [1, 4] },
1: { id: 1, title: 'Africa', childIds: [2, 3] },
2: { id: 2, title: 'Egypt', childIds: [] },
3: { id: 3, title: 'Kenya', childIds: [] },
4: { id: 4, title: 'Europe', childIds: [5] },
5: { id: 5, title: 'France', childIds: [] },
};
export default function TravelPlan() {
const [plan, setPlan] = useState(initialPlan);
function handleComplete(parentId, childId) {
const parent = plan[parentId];
// A new version of the parent place
// that doesn't include this child ID.
const nextParent = {
...parent,
childIds: parent.childIds.filter(id => id !== childId)
};
// A new table with the updated parent.
setPlan({
...plan,
[parentId]: nextParent
});
}
const root = plan[0];
return (
<>
<h2>Places to visit</h2>
<ol>
{root.childIds.map(id => (
<PlaceTree
key={id}
id={id}
parentId={0}
placesById={plan}
onComplete={handleComplete}
/>
))}
</ol>
</>
);
}
function PlaceTree({ id, parentId, placesById, onComplete }) {
const place = placesById[id];
const childIds = place.childIds;
return (
<li>
{place.title}
<button onClick={() => onComplete(parentId, id)}>Complete</button>
{childIds.length > 0 && (
<ol>
{childIds.map(childId => (
<PlaceTree
key={childId}
id={childId}
parentId={id}
placesById={placesById}
onComplete={onComplete}
/>
))}
</ol>
)}
</li>
);
}
// A run only mounts. Act like a user: complete Kenya, then Europe.
function completeButton(title) {
const li = [...document.querySelectorAll('li')].find(li => li.firstChild.textContent === title);
return li.querySelector('button');
}
setTimeout(() => {
completeButton('Kenya').click();
setTimeout(() => {
completeButton('Europe').click();
setTimeout(() => {
console.log('initialPlan[1].childIds is still', initialPlan[1].childIds.join(', '));
}, 50);
}, 50);
}, 50);