Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 超过最大调用堆栈大小-已连接的React组件_Javascript_Reactjs_Ecmascript 6 - Fatal编程技术网

Javascript 超过最大调用堆栈大小-已连接的React组件

Javascript 超过最大调用堆栈大小-已连接的React组件,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我一辈子都搞不懂自己为什么会出错: 超过最大调用堆栈大小 当运行此代码时。如果我不这样评论: const tabs=this.getTabs(断点、面板、selectedTab) 错误消失了。我甚至注释掉了其他setState()调用,试图缩小问题的范围 代码(删除了额外的函数): 导出默认类SearchTabs扩展组件{ 构造函数(){ 超级(); 此.state={ 筛选器:null, 筛选器:null, isDropdownOpen:错误, selectedFilter:空, }; thi

我一辈子都搞不懂自己为什么会出错:

超过最大调用堆栈大小

当运行此代码时。如果我不这样评论:

const tabs=this.getTabs(断点、面板、selectedTab)

错误消失了。我甚至注释掉了其他
setState()
调用,试图缩小问题的范围

代码(删除了额外的函数):

导出默认类SearchTabs扩展组件{
构造函数(){
超级();
此.state={
筛选器:null,
筛选器:null,
isDropdownOpen:错误,
selectedFilter:空,
};
this.getTabs=this.getTabs.bind(this);
this.tabChanged=this.tabChanged.bind(this);
this.setSelectedFilter=this.setSelectedFilter.bind(this);
this.closeDropdown=this.closeDropdown.bind(this);
this.openDropdown=this.openDropdown.bind(this);
}
componentDidMount(){
const{panels}=this.props;
如果(!panels | |!panels.members | | panels.members.length==0){
this.props.fetchSearch();
}
}
获取选项卡(断点、面板、选定选项卡){
const tabs=panels.member.map((panel,idx)=>{
const{id:panelId,headline}=panel;
const url=getHeaderLogo(面板,50);
const item=url?:标题;
const classname=类名称([
searchResultsTheme.tabItem,
(idx==selectedTab)?searchResultsTheme.active:空,
]);
this.setState({filter:this.renderFilters(
面板
断点,
此.setSelectedFilter,
this.state.selectedFilter,
this.state.isDropdownOpen,
)| |空});
返回(
);
});
返回标签;
}
render(){
const{panels,selectedTab}=this.props;
如果(!panels | | panels.length==0)返回null;
const tabs=this.getTabs(断点、面板、selectedTab);
返回(
    {tabs}
{this.state.filter} ); } } export const TabItem=({classname,content,onclick,key})=>(
  • {content}
  • );
    由于此循环:

      render  ----->   getTabs  ----->  setState -----
        ^                                            |
        |                                            |
        |____________________________________________v
    
    您正在从render调用getTabs方法,并在其中执行
    setState
    setState
    将触发重新渲染,再次执行getTabs无限循环

    getTabs
    方法中删除
    setState
    ,它将工作

    另一个问题是:

    onclick={this.tabChanged(idx, headline)}
    
    我们需要为onClick事件分配一个函数,我们不需要调用它,但在这里您要调用该方法,请使用以下方法:

    onclick={() => this.tabChanged(idx, headline)}
    

    根据文档,您可能会在组件更新中调用两次
    setState
    。每次尝试渲染组件时,也会在3个不同的位置调用
    setState
    。每次调用
    setState
    ,组件都将重新加载。这将导致一个无限循环。天啊,是的,我现在正在重构这段代码,真是一团糟。这就是我在重构过程中遇到的问题,我发现错误的做法已经完成,它们导致我画画。不是这样,我尝试在getTabs中注释setState,没有什么区别。我注释掉了,它就消失了……如果我们在render中执行setState,hmmm代码将无法工作,它将一直抛出错误:“超出了最大调用堆栈大小”:)您可以调用该函数并返回TabItems,但不要执行setState、重新排列代码并在其他位置执行setState,如componentDidMount生命周期方法或任何事件中。在这种情况下,在中执行,如果需要,也可以禁用该选项,请选中此项
    onclick={() => this.tabChanged(idx, headline)}