的onClick处理程序被触发每个渲染周期

问题描述:

我有这样的onClick处理程序被触发每个渲染周期

this.state = { 
    selectedTab : 'tab1' 
} 

然后

默认状态我渲染方法这样

render(){ 
    const { selectedTab } = this.state; 
    return(
     <li>tab1</li><li>tab2</li> 
     <div id="content"> 
     {selectedTab == 'tab1' ? this.renderTab1Content() : this.renderTab2Content()} 
     </div> 
    ) 
} 

上面的一切工作。但我没有使用click事件实现切换选项卡。

我试图onclick事件绑定在我li改变selectedTab的状态,但我得到了无限循环的错误。像这样

<li onClick={this.setState({selectedTab :'tab1'})}>Tab 1</li> 
<li onClick={this.setState({selectedTab :'someothertab'})}>Tab 2/li> 

为什么?

这个错误是因为你onClick处理器期望的功能,但你叫在事件上设置状态的语句,因此每次使用setState状态更改时,都会再次调用渲染,因此onClick再次调用setState触发无限循环。您可以通过在onClick事件使用arrow function或调用单独的函数

<li onClick={() => this.setState({selectedTab :'tab1'})}>Tab 1</li> 

handleClick =() =>{ 
    this.setState({selectedTab :'tab1'}) 
} 


<li onClick={this.handleClick}>Tab 1</li> 
+0

哦,这是一个粗心的错误! –

+0

非常感谢! –

+0

没问题,很乐意帮忙 –

每次你的li被渲染的时候,的setState被自动调用,因此你进入一个循环。你应该做这样的事情。

在这样

setActiveTab = (tab) => { 
this.setState({selectedTab : tab}); 
} 

然后在您的渲染方法的组件创建方法重写li这样

<li onClick={() => this.setActiveTab('tab1')}>Tab 1</li> 
<li onClick={() => this.setActiveTab('someothertab')}>Tab 2/li> 

我将介绍“在这里高阶函数”的概念做到这一点。

基本上,高阶函数是返回另一个函数的函数。

让我们修改onClick处理程序并使其成为“高阶函数”。

// Original function 
setActiveTab = (activeTab) => { 
    this.setState({ activeTab }); 
} 

// Higher order function 
setActiveTab = (activeTab) => { 
    // Here, we already "remember" name of tab which becomes active after click. 
    // Return "true" `onClick` handler from this place. 
    return() => { 
    // Finaly set state after click. 
    this.setState({ activeTab }); 
    } 
} 

渲染函数的外观如何?

<li onClick={this.setActiveTab('tab1')}>Tab 1</li> 
<li onClick={this.setActiveTab('someothertab')}>Tab 2/li> 

更好,是不是?