【问题标题】:React - How to condition the execution of a function on the state (on the change of state)?React - 如何以状态(状态变化)为条件执行函数?
【发布时间】:2017-08-02 21:44:44
【问题描述】:

我有一个按钮。如果单击它,文本会更改(由于 setState({}))。我想(仅当)单击按钮并且文本更改以弹出模式组件。模态弹出功能再次改变状态。模态也应在更改后 1-3 秒弹出。我尝试使用 timeout(function...) 但这没有用。调用 2 个函数仅适用于文本更改,但不适用于模式弹出窗口。任何帮助都会很棒!

    class App extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                display: false,
                modal: false
            }
            this.onClick = this.onClick.bind(this);
        }
        change() {
            this.setState({
                display: !this.state.display
            })
        };
        toggle() {
            if (this.state.modal == true) {
                this.setState({
                    modal: !this.state.modal
                })
            }
        };

        onClick() {
            this.change()
            this.toggle()

        }
        render() {
            if (this.state.display) {
                return <a onClick={() => { change(); toggle();}}><p>Hello</p> </a>
                    <Modal onClick={this.onClick} status={this.state.modal}/>

            } else {
                return <a onClick={this.onClick}> <p>Bye</p></a>
            }
        }
    }

洞察我的 Modal 组件:

....
    return(
  <div className="modal" data-status={this.props.status}>
....

【问题讨论】:

  • 这一行在您发布的代码中永远不会是真的:if (this.state.modal == true) {

标签: javascript reactjs setstate


【解决方案1】:

如果所有这些逻辑都必须存在于组件中,那么检查状态变化的一个地方是componentDidUpdate() 生命周期函数。如果我正确理解您的意图,代码可能如下所示:

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            display: false,
            modal: false
        }

        this.toggleDisplay = function(){
          this.setState({
            display: !this.state.display
          });
        }.bind( this );

        this.showModal = function(){
          this.setState( { modal: true } );
        }.bind( this );

        this.hideModal = function(){
          this.setState( { modal: false } );
        }.bind( this );
    }

    componentDidUpdate( prevProps, prevState ){
      // if toggled to display
      if( !prevState.display && this.state.display ){
        if( !this.state.modal ){
          setTimeout( this.showModal, 3000 ); //delay 3 seconds
        }
      }

      // if toggled to not display
      else if( prevState.display && !this.state.display ){
        if( this.state.modal ){
          this.hideModal(); //assuming you don't want to delay hide
        }
      }
    }

    render() {
      const msg = this.state.display ? 'Hello' : 'Bye',
          modal = this.state.modal ? (
            <Modal onClick={this.toggleDisplay} status={this.state.modal}/>
          ) : null;

      return (
        <div>
          <a onClick={this.toggleDisplay}}><p>{msg}</p></a>
          {modal}
        </div>
      );
    }
}

据我所知,如果在计时器执行之前发生状态更改,则很容易出错,但我将把这个问题留给你练习。

【讨论】:

  • 非常感谢您的回答!!我忘记添加模态组件的代码(现在在我的编辑中)。除非我包含它,否则模态不会弹出,但我想我没有在正确的位置包含它,而是它:
  • 好吧,我将其添加到我的答案中。请记住,render 只能返回单个组件,因此&lt;a&gt;&lt;Modal&gt; 需要包装在容器中,例如&lt;div&gt;
  • 非常感谢您的帮助!!现在的问题是我无法关闭模式。我尝试将 hideModal 函数(
  • 因为我们将hideModal() 传递给Modal 作为名称为onClick 的道具,所以您需要将该函数传递给在Modal 中返回的&lt;div&gt;。例如&lt;div className='modal' onClick={this.props.onClick}&gt;
  • 谢谢,它现在可以工作了——只是我得到了非常奇怪的结果。当我打开模态并且不关闭它时,将鼠标移开或滚动该模态开始到处弹出
猜你喜欢
  • 2022-12-15
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 2017-08-03
  • 2021-06-03
  • 2020-08-04
  • 1970-01-01
相关资源
最近更新 更多