React.js组件甚至不呈现状态更改

时间:2019-01-15 03:47:13

标签: javascript reactjs state

警报模式对话框即使状态更改也不改变

我共享了Codepen here。 这是组件。

class RecordingReports extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      dialog: null,
      newContent: {
        contentType: "recording"
      }
    };
  }
  toggleContentType = () => {
    let newContent = this.state.newContent;
    this.setState({
      newContent: {
        ...newContent,
        contentType:
          newContent.contentType == "recording" ? "report" : "recording"
      }
    });
  };
  showDialog = () => {
    this.setState({
      dialog: (
        <div>
          <button
            onClick={() => {
              this.toggleContentType();
            }}
          >
            {this.state.newContent.contentType} // it remains recording
          </button>
        </div>
      )
    });
  };
  render() {
    console.log(this.state.newContent); //this shows state changes
    return (
      <div>
        {this.state.dialog} 
        <button onClick={() => this.showDialog()} >show Toggle Button</button>
      </div>
    );
  }
}

要测试第一次单击“显示切换”,然后看到标题为recording的按钮,我希望在单击时进行切换,但是从不这样做。

我共享了Codepen here

如果您看到控制台,则会看到它更改状态。

我不确定这是怎么回事,

谢谢

2 个答案:

答案 0 :(得分:0)

您不需要处于状态的对话框,该对话框不会在对话框中更改,这不会更改,因为您未设置状态。对话框的onclick再次设置了相同的状态,而没有更改记录类型。

问题:

this.setState({
      dialog: (
        <div>
          <button
            onClick={() => {
              this.toggleContentType();
            }}
          >
            {this.state.newContent.contentType} // it remains recording
          </button>
        </div>
      )
    });

解决方案:

constructor(props) {
    super(props);

    this.state = {
      dialog: null,
      newContent: {
        contentType: "recording"
      },
      showDialog: false
    };
  }
  toggleContentType = () => {
    let newContent = this.state.newContent;
    this.setState({
      newContent: {
        ...newContent,
        contentType:
          newContent.contentType === "recording" ? "report" : "recording"
      }
    });
  };
  dialog = () => {
    return this.state.showDialog && <div>
      <button
        onClick={() => {
          this.toggleContentType();
        }}
      >
        {this.state.newContent.contentType} // it remains recording
      </button>
    </div>

  };

  showHideDialog = () => {
    this.setState({ showDialog: !this.state.showDialog });
  }
  render() {

    return (
      <div>
        {this.dialog()}
        <button onClick={() => this.showHideDialog()} >show Toggle Button</button>
      </div>
    );
  }

demo

答案 1 :(得分:0)

是的,它不会改变,因为dailog状态内的整个元素不只是javascript元素,

解决方案是将Dialog作为另一个组件单独传递并传递道具,这样您的代码将更加清晰易读。

const Dialog = ({ show, onClick, newContent }) => {
  return !show ? null : (
    <div>
      <button onClick={onClick}>{newContent.contentType}</button>
    </div>
  );
};

class RecordingReports extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      showDialog: false,
      newContent: {
        contentType: "recording"
      }
    };
  }

  toggleContentType = () => {
    let newContent = this.state.newContent;
    this.setState({
      newContent: {
        ...newContent,
        contentType: newContent.contentType == "recording" ? "report" : "recording"
      }
    });
  };

  toggleDialog = () => {
    this.setState({
      showDialog: !this.state.showDialog
    });
  };

  render() {
    console.log(this.state.newContent); //this shows state changes
    return (
      <div>
        <Dialog show={this.state.showDialog} onClick={this.toggleContentType} newContent={this.state.newContent}/>
        <button onClick={this.toggleDialog}>show Toggle Button</button>
      </div>
    );
  }
}

ReactDOM.render(<RecordingReports />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"><div>