Javascript 当使用ComponentDidMount()时,我发现了这个错误:Can';t调用setState

Javascript 当使用ComponentDidMount()时,我发现了这个错误:Can';t调用setState,javascript,reactjs,redux,Javascript,Reactjs,Redux,我发现了这个错误: 无法对未安装的组件调用setState(或forceUpdate)。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务 上下文:当我连接时,我在主页上,此页面不包含面包屑,但如果我进入活动页面(也是组件名称),我有面包屑(组件名称),我发现了此错误 在我看到的另一篇文章中,他们说可能在组件上异步挂载问题,但我认为我的问题不同,我找不到解决方案 我的代码如下所示: import React

我发现了这个错误:

无法对未安装的组件调用setState(或forceUpdate)。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务

上下文:当我连接时,我在主页上,此页面不包含面包屑,但如果我进入
活动页面
(也是组件名称),我有
面包屑
(组件名称),我发现了此错误

在我看到的另一篇文章中,他们说可能在
组件上异步挂载问题,但我认为我的问题不同,我找不到解决方案

我的代码如下所示:

import React,{Component}来自'React';
从“道具类型”导入道具类型;
从'react redux'导入{connect};
从“类名称”导入类名称;
从“对象分配”导入对象分配;
从“react router”导入{withRouter};
进口{
面包屑,
面包屑,路径,标识,
面包屑
}从“常数”开始;
从“actions/breadcrumbs”导入{getEntityById,setUpdatedBreadcrumbs};
从“/style.scss”导入样式;
类Breadcrumbs扩展组件{
建造师(道具){
超级(道具);
此.state={
面包屑:[],
名称:{}
};
this.setbreadcrumps=this.setbreadcrumps.bind(this);
this.loadEntityNameById=this.loadEntityNameById.bind(this);
}
组件willmount(){
这是我的面包屑();
}
组件将接收道具(下一步){
const{isWillUpdate:newIsWillUpdate}=nextProps;
const{isWillUpdate,saveUpdatedBreadcrumbs}=this.props;
if(isWillUpdate==false&&newIsWillUpdate==true){
这是我的面包屑();
saveUpdatedBreadcrumbs();
}
}
(){
const{params,path}=this.props.match;
让currentPath='';
const pathSplitedAndExtendet=path.split(“/”)
.filter(项目=>!!项目)
.map(项目=>{
if(项[0]===':'&&item.slice(1)!=='adPage'){
常量参数名称=item.slice(1);
this.loadEntityNameById(
参数名,
参数[参数名称]
);
返回{
路由:`/${params[parameterName]}${BREADCRUMBS\u ROUTES\u FOR_ID[parameterName]}`,
参数:parameterName
};
}
返回{
路由:`/${item}`,
参数:“”
};
});
const breadcrumbs=路径拆分和扩展
.filter(item=>item.parameter!=='adPage')
.map((项目)=>{
const indexOfRoute=currentPath.indexOf(item.route);
if(currentPath.slice(indexOfRoute)!==item.route){
currentPath=`${currentPath}${item.route}`;
}
返回({
…项目,
名称:面包屑路径[item.route]| |“”,
路由:currentPath
});
});
this.setState({breadcrumbs});
}
异步loadEntityNameById(参数,id){
const{loadEntityById}=this.props;
等待loadEntityById(面包屑_端点[参数],id)
。然后((数据)=>{
this.setState({names:objectAssign(this.state.names,{[参数]:{id,name:data.name})});
});
}
render(){
const{breadcrumbs,names}=this.state;
const{showBreadcrumbs}=this.props;
返回(
{
showBreadcrumbs&&breadcrumbs
.map((项目、索引)=>{
返回(
{}}
onClick={item.route?()=>this.props.history.push(item.route):null}
>
{`${item.name | |(名称[item.parameter]
?名称[item.parameter]。名称:“…”)}
${((breadcrumbs.length>1)和&(index!==breadcrumbs.length-1))?'>':'}
`}
);
})
}
);
}
}

导出默认连接(mapStateToProps、mapDispatchToProps)(带路由器(面包屑))
您不能在
componentWillMount
中调用
setState
请尝试使用
componentDidMount
而不是
componentWillMount
中调用
setState
尝试使用
componentDidMount
执行异步操作(
loadEntityNameById
)设置组件完成时的状态。到那时,您的
Breadcrumbs
组件可能已卸载,并引发错误。

您正在执行一个异步操作(
loadEntityNameById
),该操作设置组件完成时的状态。到那时,您的
Breadcrumbs
组件可能已经卸载,并抛出错误

无法对未安装的组件调用setState(或forceUpdate)。这是一个no-op,但它表示应用程序中存在内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务

此错误消息明确指出应用程序存在内存泄漏。这到底是怎么回事

好的,您正在
setbreadcrumps
方法中使用异步操作(loadEntityNameById)。在
组件willmount
组件willreceiveprops
中调用的。这意味着,当您从
activitypage
组件转到
BreadCrumb
组件时,它将执行异步操作,即
loadEntityNameById
在后台运行,仅在完成后设置状态。但在此之前,
BreadCrumb
组件可能会卸载。react应用程序不允许您更新未安装组件的状态

此外,您根本不应该使用
componentWillMount
方法。改用
componentDidMount
hook

要解决此问题,您可以设置一个标志,如
componentDidMount() {
  // component is mounted, set the didMount property on BreadCrumb component
  // you can use any name instead of didMount what you think is proper
  this.didMount = true
  // now, you can update the state
  if(this.didMount) { // be sure it's not unmounted
    this.setState({names: ...})
  }
componentWillUnmount() {
  this.didMount = false // component is unmounted