如何在 ReactJS 中显示模态对话框?

How to display a modal dialog box in ReactJS?

我是 JavaScript 和 ReactJS 的新手。

我有一个应用程序,用户可以在其中输入他或她的电子邮件地址。然后 我尝试创建用户记录。如果出现问题,我想显示一个 带有错误消息的模态 window。

handleSubmit(evt) {
  evt.preventDefault()
  var email = this.state.email
  var userCreationResult = this.createUser(email)
  if (!userCreationResult.success) {
    // The modal window should be displayed here
    return
  }
}

react-bootstrap 有模态 windows 的组件。我基于它创建了一个class:

import React, { Component, Modal } from 'react';

class ModalMessageBox extends Component {
  constructor() {
    super()
  }
  render() {
    return (
      <div>
        <Modal>
          <Modal.Header closeButton>
            <Modal.Title>Modal heading</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <h4>An error occured</h4>
            <p>Test error message.</p>
          </Modal.Body>
        </Modal>
      </div>
    )
  }
}

export default ModalMessageBox;

当出现用户创建错误时,我尝试使用此代码显示它:

handleSubmit(evt) {
  evt.preventDefault()
  var email = this.state.email
  var userCreationResult = this.createUser(email)
  if (!userCreationResult.success) {
    var dialog = new ModalMessageBox();
    ReactDOM.render(dialog, document.getElementById('root'));

这不起作用 -- 我收到错误 ReactDOM.render(): Invalid component element.

在 React 中显示模态对话框的正确方法是什么?

更新 1(2017 年 7 月 27 日 15:27 MSK):

Class,其中包含提交处理程序。

import React, { Component } from 'react';
import { 
  FormGroup, 
  ControlLabel, 
  FormControl, 
  HelpBlock, 
  Button,
  Modal,
  Popover,
  Tooltip,
  OverlayTrigger
} from 'react-bootstrap';
import style from './style';
import FallibleOperationResult from './FallibleOperationResult';
import ModalMessageBox from './ModalMessageBox';
import ReactDOM from 'react-dom';

class SignUpForm extends Component {
  constructor(props) {
    super(props)
    this.state = {email: ''};
    this.handleEmailChange = this.handleEmailChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }
  handleEmailChange(evt) {
    this.setState({ email: evt.target.value });
  }
  handleSubmit(evt) {
    evt.preventDefault()
    var email = this.state.email
    var userCreationResult = this.createUser(email)
    if (!userCreationResult.success) {
      displayUserCreationError(userCreationResult)
      console.log("Error detected")
      return
    }

    console.log("Submit button pressed, e-mail: " + this.state.email)
  }
  displayUserCreationError(userCreationResult) {
    // Display of the moal dialog should be implemented here
    // var dialog = new ModalMessageBox();
    // ReactDOM.render(dialog, document.getElementById('root'));
    console.log("User cannot be created ('" + userCreationResult + "'");

    return;
  }
  createUser(email) {
    return new FallibleOperationResult(
      false, 
      'User ' + email + ' cannot be created', 
      undefined
    );
  }
  render() {
    return (
      <div style={style.signUpForm}>
        <form onSubmit={ this.handleSubmit }>
          <FormGroup
            controlId="formBasicText"
          >
          <FormGroup>
            <ControlLabel>Email address</ControlLabel>
            <FormControl 
              type="email" 
              placeholder="Enter email"
              onChange={ this.handleEmailChange }
            />
          </FormGroup>
          <Button type="submit">Sign Up</Button>
          <p>Your password will be sent to your e-mail address.</p>
          </FormGroup>
        </form>
      </div>
    )
  }
}

export default SignUpForm;

整个应用应该只有一个ReactDOM.render。您必须根据状态在显示内容和不显示内容之间切换。

由于您没有提供父项 class,我将自行承担并提供指导。

handleSubmit(evt) {
  evt.preventDefault()
  var email = this.state.email
  var userCreationResult = this.createUser(email)
  if (!userCreationResult.success) {
    // The modal window should be displayed here
    // you must set the state here
    this.setState({
      userFailed: true
    });
    return
  }
}

并在渲染中:

render() {
  return (
    <div>
       // your usual code here
       // render the modal based on state here
       { this.state.userFailed ? < ModalMessageBox /> : null }
    </div>
  )
}

更新:

import React, { Component } from 'react';
    import { 
      FormGroup, 
      ControlLabel, 
      FormControl, 
      HelpBlock, 
      Button,
      Modal,
      Popover,
      Tooltip,
      OverlayTrigger
    } from 'react-bootstrap';
    import style from './style';
    import FallibleOperationResult from './FallibleOperationResult';
    import ModalMessageBox from './ModalMessageBox';
    import ReactDOM from 'react-dom';

    class SignUpForm extends Component {
      constructor(props) {
        super(props)
        this.state = {
          email: '',
          userCreationFailed: false
        };
        this.handleEmailChange = this.handleEmailChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.displayUserCreationError = this.displayUserCreationError.bind(this);
      }
      handleEmailChange(evt) {
        this.setState({ email: evt.target.value });
      }
      handleSubmit(evt) {
        evt.preventDefault()
        var email = this.state.email
        var userCreationResult = this.createUser(email)
        if (!userCreationResult.success) {
          displayUserCreationError(userCreationResult)
          console.log("Error detected")
          return
        }
        
        console.log("Submit button pressed, e-mail: " + this.state.email)
      }
      displayUserCreationError(userCreationResult) {
        this.setState({
          userCreationFailed: true
        });
        console.log("User cannot be created ('" + userCreationResult + "'");
            
        return;
      }
      createUser(email) {
        return new FallibleOperationResult(
          false, 
          'User ' + email + ' cannot be created', 
          undefined
        );
      }
      render() {
        return (
          <div style={style.signUpForm}>
            <form onSubmit={ this.handleSubmit }>
              <FormGroup
                controlId="formBasicText"
              >
              <FormGroup>
                <ControlLabel>Email address</ControlLabel>
                <FormControl 
                  type="email" 
                  placeholder="Enter email"
                  onChange={ this.handleEmailChange }
                />
              </FormGroup>
              <Button type="submit">Sign Up</Button>
              <p>Your password will be sent to your e-mail address.</p>
              </FormGroup>
            </form>
            {this.state.userCreationFailed ? <ModalMessageBox /> : undefined}
          </div>
        )
      }
    }

    export default SignUpForm;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>