Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Suggestion]: Improvements to an example in the document #8141

Open
@jx-xue

Description

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(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 (


  • {place.title}
    <button type={'button'} onClick={() => onComplete(parentId, id)}>
    Del

    {
    childIds.length > 0 &&

      {
      childIds.map(childId => )
      }

    }

  • )
    }

    Metadata

    Metadata

    Assignees

    No one assigned

      Type

      No type

      Projects

      No projects

      Milestone

      No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

          AltStyle によって変換されたページ (->オリジナル) /