删除影响 DOM 中某些内容的内容时出现 NotFoundError
NotFoundError when deleting something that affects something in the DOM
我创建了一个笔记应用程序。在首页上有类别和注释。您可以单击类别并获取该类别下的所有笔记。我刚刚添加了一个按钮,可以让您删除该类别及其所有注释,然后导航回首页。它看起来像这样:
按钮:
<IonRow>
<IonButton onClick={deletecat} >
Delete Category
</IonButton>
</IonRow>
这里是 deletecat
函数:
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')
}
当我点击我的按钮时出现这个错误:
NotFoundError: Node.removeChild: The node to be removed is not a child of this node
这个问题实际上是在 SO 之前 (React Error: NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node) 上解决的,但他们的具体解决方案是针对 jquery。但是我觉得概念是一样的:
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
我该如何解决这个问题?有什么方法可以重新渲染 DOM ,而不会尝试查找之前渲染的内容?我还能如何解决这个问题?
编辑:这是首页:
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>
根据您上面的评论,要使更改同时反映在首页和组件页面上,您可以在父组件级别从 API 调用数据,然后将数据和 setData 向下传递为组件页面的道具。
如果首页和组件页是router下的兄弟,那么可以在router组件中拉取数据,share as props or implement the useContext hook共享数据
更改笔记内容和删除类别等更新应该发生在 front-end 上,然后通过异步获取请求更新到 back-end。
问题来自 API 的更新之间的异步延迟与调用 router.push
方法的同步卸载竞争。通过依赖本地状态数据,你应该摆脱你的问题。
我创建了一个笔记应用程序。在首页上有类别和注释。您可以单击类别并获取该类别下的所有笔记。我刚刚添加了一个按钮,可以让您删除该类别及其所有注释,然后导航回首页。它看起来像这样:
按钮:
<IonRow>
<IonButton onClick={deletecat} >
Delete Category
</IonButton>
</IonRow>
这里是 deletecat
函数:
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')
}
当我点击我的按钮时出现这个错误:
NotFoundError: Node.removeChild: The node to be removed is not a child of this node
这个问题实际上是在 SO 之前 (React Error: NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node) 上解决的,但他们的具体解决方案是针对 jquery。但是我觉得概念是一样的:
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
我该如何解决这个问题?有什么方法可以重新渲染 DOM ,而不会尝试查找之前渲染的内容?我还能如何解决这个问题?
编辑:这是首页:
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>
根据您上面的评论,要使更改同时反映在首页和组件页面上,您可以在父组件级别从 API 调用数据,然后将数据和 setData 向下传递为组件页面的道具。
如果首页和组件页是router下的兄弟,那么可以在router组件中拉取数据,share as props or implement the useContext hook共享数据
更改笔记内容和删除类别等更新应该发生在 front-end 上,然后通过异步获取请求更新到 back-end。
问题来自 API 的更新之间的异步延迟与调用 router.push
方法的同步卸载竞争。通过依赖本地状态数据,你应该摆脱你的问题。