'NotFoundError when deleting something that affects something in the DOM

I've created a notes app. On the front page it has categories and notes. You can click on the categories and get all of the notes under that category. I just added a button that lets you delete the category and all of its notes and then navigate back to the front page. It looks like this:

Button:


<IonRow>
    <IonButton onClick={deletecat} >
        Delete Category
    </IonButton>
</IonRow>

Here is the deletecat function:

const deletecat = () => {
        const trashcategory = ({category}) => {
        try {
        fetch(`https://fakeurl.com/delcat/${category}/`, {
        method: "DELETE",
        mode: "cors",
        headers: {
        "Content-Type": "application/json",
        },
        })
        } catch (error) {
        console.log("error time!", error);
        return false;
        }
        };
    trashcategory({category})
    router.push('/notes')
    }

When I click on my button I get this error:

NotFoundError: Node.removeChild: The node to be removed is not a child of this node

This issue was actually addressed on SO before (React Error: NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node), but their specific solution was for jquery. But I think the concept is the same:

This issue occurs when you:

1. Render something using React
2. Then, you manipulate DOM rendered by React with external script
3. Now on the next render cycle(re-render), React doesn't find the DOM node it rendered previously as its already modified/removed by external script

How do I resolve this? Is there any way I can re-render the DOM in a way where it doesn't try and look for what was rendered previously? How else might I get around this?

edit: This is the front page:


    useEffect(() => {

        getcategories({username})



        getnotes({username})

        console.log("USEEFFECTTIME")


    },[]);


    const getcategories = ({ username }) => {
        
    try {
    
    fetch(`https://fakeurl.com/getcategories`, {
    method: "POST",
    mode: "cors",
    headers: {
    "Content-Type": "application/json",
    },
    body: JSON.stringify({username}),
    })
    .then(res => res.json())
    .then(data => {
        setCategorydata(data);
        setLoading(false);
    })
    } catch (error) {
    console.log("error time!", error);
    return false;
    }
    };
    console.log('before get categories')





    const getnotes = async ({ username }) => {
    
    try {
    //await fetch(`/getnotes`, {
    await fetch(`https://fakeurl.com/getnotes`, {
    method: "POST",
    mode: "cors",
    headers: {
    "Content-Type": "application/json",
    },
    body: JSON.stringify({username}),
    })
    .then(res => res.json())
    .then(data2 => {
        setNotedata(data2);
        setLoading2(false)
    })
    } catch (error) {
    console.log("error time!", error);
        return false;
    }
    };

const categories = categorydata.categories
const notes = notedata.notes


<IonSlides id="slider" options={{ slidesPerView: "auto", zoom: true, grabCursor: true }} className={ `${ styles.categorySlider } ion-padding-bottom` }>
                    { categories.map((category, index) => {

                        const noteCount = notes.filter(n => n.note_category === category.id).length;

                        return (

                            <IonSlide key={ `categorySlide_${ index }`}>
                                <IonCol className="ion-text-left">
                                    <IonCard routerLink={`/categorypage/${category.id}`}>
                                        <IonCardHeader className="ion-no-padding" >

                                            <div className={ styles.slideCount }>
                                                <h6>{ noteCount } { noteCount === 1 ? "note" : "notes" } </h6>
                                            </div>
                                            <div className={ styles.slideHeader }>
                                                <h4 style={{color:"black"}}>{ category.category }</h4>
                                            </div>
                                        </IonCardHeader>

                                        <IonCardContent>
                                            <div className={ styles.categoryColor } style={{ borderBottom: `2px solid ${ category.color }` }}></div>
                                        </IonCardContent>
                                    </IonCard>
                                </IonCol>
                            </IonSlide>
                        );
                    })}
                </IonSlides>
                
                <IonGrid className={ styles.bottomContainer }>
                    <IonRow>
                        <IonCol size="12" className="ion-padding-start">
                            <IonCardSubtitle className={ styles.heading }>
                                Recent Notes
                            </IonCardSubtitle>
                        </IonCol>
                    </IonRow>
                    
                    <div className={ styles.recentNotes }>

                        { notes.slice(0).reverse().map((note, index) => {

                            return (

                                <IonRow key={ `note_${ index }` } className="animate__animated animate__faster" id={ `noteRow_${ note.id }` }>
                                    <IonCol size="12">
                                        <Link to={`/Update/${note.id}`}>
                                            <h2>{note.note_name}</h2>
                                        </Link>
                                    </IonCol>
                                </IonRow>
                            );
                        })}
                    </div>
                </IonGrid>



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source