Javascript 当从依赖于要呈现的状态的元素调用时,setState()不会更改状态

Javascript 当从依赖于要呈现的状态的元素调用时,setState()不会更改状态,javascript,reactjs,state,Javascript,Reactjs,State,我有一个类似这样的小组件(下面的代码被简化为所需的部分),当更新状态时,它的行为非常奇怪 class Componenent extends React.Component { constructor(props) { super(props); this.state = {showStuff: false}; } render() { return( //Markup {this.state.showStuff &&am

我有一个类似这样的小组件(下面的代码被简化为所需的部分),当更新状态时,它的行为非常奇怪

class Componenent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showStuff: false};
  }

  render() {
    return(
      //Markup
        {this.state.showStuff && (
          <button onClick={() => this.setState({showStuff: false})} />
        )}
      // More Markup
    );
  }
}

通过编写
onClick={this.setState({showtuff:false})}
按钮一呈现,实际上就是在调用
setState

您希望为
onClick
提供函数引用,而不是在渲染时立即调用它

<button onClick={() => this.setState({showStuff: false})} />
this.setState({showtuff:false})}/>
如果您的按钮位于另一个元素中,该元素具有一个不希望在同一次单击中运行的单击侦听器,则必须确保单击事件不会传播到父元素

<button
  onClick={(event) => {
    event.stopPropagation();
    this.setState({showStuff: false});
  }}
/>
{
event.stopPropagation();
this.setState({showStuff:false});
}}
/>

通过编写
onClick={this.setState({showtuff:false})}
在呈现按钮后,您实际上正在调用
setState

您希望为
onClick
提供函数引用,而不是在渲染时立即调用它

<button onClick={() => this.setState({showStuff: false})} />
this.setState({showtuff:false})}/>
如果您的按钮位于另一个元素中,该元素具有一个不希望在同一次单击中运行的单击侦听器,则必须确保单击事件不会传播到父元素

<button
  onClick={(event) => {
    event.stopPropagation();
    this.setState({showStuff: false});
  }}
/>
{
event.stopPropagation();
this.setState({showStuff:false});
}}
/>

实际上onClick prop需要一个函数,您已经提供了一个函数调用,因此每次呈现组件时都会调用setState,而不是单击时

试试这个:

<button onClick={() => this.setState({showStuff: false})} />
this.setState({showtuff:false})}/>

应该按照您预期的方式操作:)

实际上onClick道具需要一个函数,您已经提供了一个函数调用,因此每次呈现组件时都会调用setState,而不是单击时

试试这个:

<button onClick={() => this.setState({showStuff: false})} />
this.setState({showtuff:false})}/>

应该按照您期望的那样操作:)

在我更新showStuff true时工作得非常好(请参阅下面更新的代码)。我猜应该是设置showStuff的代码:true不起作用。我还在按钮中添加了一些文本

import React from 'react'
import ReactDOM from 'react-dom'
class Componenent extends React.Component {
    constructor(props) {
      super(props);
      this.state = {showStuff: true};
    }

    render() {
      return(
        <div>

          {this.state.showStuff && (
            <button onClick={() => this.setState({showStuff: false})} > This is a button</button>
          )}
        </div>
      );
    }
  }

ReactDOM.render(<Componenent />, 
                document.getElementById('root')
);
从“React”导入React
从“react dom”导入react dom
类组件扩展了React.Component{
建造师(道具){
超级(道具);
this.state={showtuff:true};
}
render(){
返回(
{this.state.showtuff&&(
this.setState({showtuff:false}}>这是一个按钮
)}
);
}
}
ReactDOM.render(,
document.getElementById('root'))
);
点击前

点击后


在我更新showStuff true时工作得非常好(请参阅下面更新的代码)。我猜应该是设置showStuff的代码:true不起作用。我还在按钮中添加了一些文本

import React from 'react'
import ReactDOM from 'react-dom'
class Componenent extends React.Component {
    constructor(props) {
      super(props);
      this.state = {showStuff: true};
    }

    render() {
      return(
        <div>

          {this.state.showStuff && (
            <button onClick={() => this.setState({showStuff: false})} > This is a button</button>
          )}
        </div>
      );
    }
  }

ReactDOM.render(<Componenent />, 
                document.getElementById('root')
);
从“React”导入React
从“react dom”导入react dom
类组件扩展了React.Component{
建造师(道具){
超级(道具);
this.state={showtuff:true};
}
render(){
返回(
{this.state.showtuff&&(
this.setState({showtuff:false}}>这是一个按钮
)}
);
}
}
ReactDOM.render(,
document.getElementById('root'))
);
点击前

点击后


对不起,我忘了。调用实际上被包装在一个函数中。这不是问题所在。将更新代码段。抱歉,忘记了。调用实际上被包装在一个函数中。这不是问题所在。将更新代码段。抱歉,忘记了。调用实际上被包装在一个函数中。这不是问题所在。将更新代码段。@ChristophFricke没关系。你能把你的全部内容都包括在问题中吗?@ChristophFricke。您如何使用
元素Add
组件?可能您正在给它一个
道具,当更改
道具时,该组件将被丢弃并创建一个新组件。现在有
道具或类似的东西。我更新了你的沙箱,这样问题就可以重现了。有趣的我从没想过。它也适用于“真实代码”。非常感谢你。您想将此作为答案发布,以便我可以批准它吗?抱歉,忘记了。调用实际上被包装在一个函数中。这不是问题所在。将更新代码段。@ChristophFricke没关系。你能把你的全部内容都包括在问题中吗?@ChristophFricke。您如何使用
元素Add
组件?可能您正在给它一个
道具,当更改
道具时,该组件将被丢弃并创建一个新组件。现在有
道具或类似的东西。我更新了你的沙箱,这样问题就可以重现了。有趣的我从没想过。它也适用于“真实代码”。非常感谢你。您想将此作为答案发布,以便我批准吗?您应该选择一个比
组件
更具描述性的名称。还可以阅读一些关于创建好代码示例的提示。注意单词“minimal”。您在此处发布的代码似乎有许多与您的问题无关的额外行。您应该选择一个比
组件
更具描述性的名称。还可以阅读一些关于创建好代码示例的提示。注意单词“minimal”。你在这里发布的代码似乎有很多额外的行,与你的问题无关。