Javascript onClick处理程序在每个渲染周期都会触发

Javascript onClick处理程序在每个渲染周期都会触发,javascript,reactjs,Javascript,Reactjs,我有这样的默认状态 this.state = { selectedTab : 'tab1' } render(){ const { selectedTab } = this.state; return( <li>tab1</li><li>tab2</li> <div id="content"> {selectedTab == 'tab1' ? this.renderTab1Co

我有这样的默认状态

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>
   )
}
setActiveTab = (tab) => {
 this.setState({selectedTab : tab});
}
<li onClick={() => this.setActiveTab('tab1')}>Tab 1</li>
<li onClick={() => this.setActiveTab('someothertab')}>Tab 2/li>
然后

我的渲染方法是这样的

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>
   )
}
setActiveTab = (tab) => {
 this.setState({selectedTab : tab});
}
<li onClick={() => this.setActiveTab('tab1')}>Tab 1</li>
<li onClick={() => this.setActiveTab('someothertab')}>Tab 2/li>

为什么?

每次渲染
li
时,都会自动调用setState,从而进入循环。你应该这样做

像这样在组件中创建一个方法

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>
   )
}
setActiveTab = (tab) => {
 this.setState({selectedTab : tab});
}
<li onClick={() => this.setActiveTab('tab1')}>Tab 1</li>
<li onClick={() => this.setActiveTab('someothertab')}>Tab 2/li>
然后在渲染方法中,像这样重写
li

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>
   )
}
setActiveTab = (tab) => {
 this.setState({selectedTab : tab});
}
<li onClick={() => this.setActiveTab('tab1')}>Tab 1</li>
<li onClick={() => this.setActiveTab('someothertab')}>Tab 2/li>
  • this.setActiveTab('tab1')}>tab1
  • this.setActiveTab('someothertab')}>Tab 2/li>
  • 发生此错误是因为
    onClick
    处理程序需要一个函数,但您调用了一条语句来设置事件的状态,因此每次使用
    setState
    更改状态时,都会再次调用渲染,因此
    onClick
    再次调用
    setState
    ,从而触发无限循环。可以通过在
    onClick
    事件中使用
    箭头函数
    或调用单独的函数来完成此操作

    <li onClick={() => this.setState({selectedTab :'tab1'})}>Tab 1</li>
    
  • this.setState({selectedTab:'tab1'})}>Tab 1
  • handleClick=()=>{
    this.setState({selectedTab:'tab1'})
    }
    
  • 选项卡1

  • 我将介绍“高阶函数”的概念

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

    // 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 });
      }
    }
    
    onClick={() => (this.setState())}
    
    让我们修改
    onClick
    handler并使其成为“高阶函数”

    渲染函数是什么样子的

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

  • 更好,不是吗?

    每当调用setState时,都会导致运行render方法, 当你给某个变量分配一个函数调用而不是函数引用时,它会立即调用它

    在函数引用的情况下,赋值时立即调用setState,然后再次调用setState调用render,这进一步导致setState调用->setState render,这会创建一个无休止的循环

    <li onClick={this.setState({selectedTab :'tab1'})}>Tab 1</li>
    
    或者,如果使用简单函数,则可以在构造函数中绑定它们

    constructor(props){
    super(props);
    this.onClickMethod = this.onClickMethod.bind(this);
    // if this is not done then this in onclick method would not refer to the class 
    // instead it would that of assigned onClick callback as it is called 
    // by onclick Event handler hence exectuted in different context.
    }
    
    onClickMethod() {
     this.setSate();
    }
    
    <li onClick={this.onClickMethod}>Tab 1</li>
    
    构造函数(道具){
    超级(道具);
    this.onClickMethod=this.onClickMethod.bind(this);
    //如果不这样做,那么这个in-onclick方法将不会引用该类
    //相反,它将是调用时分配的onClick回调
    //因此,通过onclick事件处理程序在不同的上下文中执行。
    }
    onClickMethod(){
    这个.setState();
    }
    
  • 选项卡1

  • 哦,这是一个粗心的错误!没问题,很乐意帮忙