[Suggestion]: Improvements to an example in the document
Summary
I learned a lot from this example. After understanding it more deeply, I discovered that if a child item is the only child of its parent item, the parent item should also be deleted after deleting it. The original documentation didn't consider this, and there were many details to pay attention to during implementation. I finally completed it, and I'll post my code below.
Page
https://react.dev/learn/choosing-the-state-structure
Details
import {useImmer} from 'use-immer' import {initialTravelPlan} from './travel.ts'
interface PlaceTreeProps { id: number parentId: number plan: TravelPlan onComplete: (parentId: number, id: number) => void }
interface TravelPlan { [key: number]: { id: number title: string childIds: number[] } }
export default function HookDemo() { const [plan, setPlan] = useImmer<TravelPlan>(initialTravelPlan) const root = plan[0] const planetIds = root.childIds const handleComplete = (parentId: number, id: number) => { setPlan(draft => { if (id===0) return handleChildrenDelete(id) handleParentDelete(parentId,id)
function handleParentDelete(pId: number,cId: number) {
const parent = draft[pId]
if (!parent) return
parent.childIds = parent.childIds.filter((childId) => childId !== cId)
**// if the parent has no more children, delete it too**
if (parent.childIds.length === 0 && pId !== 0) {
const grandParentId = Object.values(draft).find(p => p.childIds.includes(pId))?.id
if (grandParentId !== undefined) {
handleParentDelete(grandParentId, pId)
}
delete draft[pId]
}
}
function handleChildrenDelete(childId: number) {
const child = draft[childId]
if (!child) return
child.childIds.forEach((grandChildId) => {
handleChildrenDelete(grandChildId)
})
delete draft[childId]
}
})
console.log(parentId, id)
}
return (
<div>
<h2>Place to Visit</h2>
<ol>
{planetIds.map((id) => (
<PlaceTree
id={id}
key={id}
parentId={0}
plan={plan}
onComplete={handleComplete}
/>
))}
</ol>
</div>
)
}
function PlaceTree({id, parentId, plan, onComplete}: PlaceTreeProps) { const place = plan[id] const childIds = place.childIds return (
-
{
childIds.map(childId => <PlaceTree key={childId} id={childId} parentId={id} plan={plan}
onComplete={onComplete}/>)
}