Search code examples
reactjsreact-nativereact-modal

ReactJS - Multiple modals


I am trying to create a simple modal form using react. I have achieved something like this:

Click here to view Codesanbox

Index.js

import React from "react";
import ReactDOM from "react-dom";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import Modal from "./components/Modal";

import "./styles.css";

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

    this.state = {
      modal1: false,
      modal2: false,
      name: "",
      modalInputName: ""
    };
  }

  handleChange(e) {
    const target = e.target;
    const name = target.name;
    const value = target.value;

    this.setState({
      [name]: value
    });
  }

  handleSubmit(e) {
    this.setState({ name: this.state.modalInputName });
    this.modalClose();
    this.modal2Close();
  }

  modalOpen() {
    this.setState({ modal1: true });
  }

  modalClose() {
    this.setState({
      modalInputName: "",
      modal1: false
    });
  }

  modal2Open() {
    this.setState({ modal2: true });
  }

  modal2Close() {
    this.setState({
      modalInputName: "",
      modal2: false
    });
  }

  render() {
    return (
      <div className="App">
        <h1>Hello!! {this.state.name}</h1>
        <a href="javascript:;" onClick={(e) => this.modalOpen(e)}>
          Open Modal
        </a>
        <Modal show={this.state.modal1} handleClose={(e) => this.modalClose(e)}>
          <h2>Hello Modal</h2>
          <div className="form-group">
            <label>Enter Name:</label>
            <input
              type="text"
              value={this.state.modalInputName}
              name="modalInputName"
              onChange={(e) => this.handleChange(e)}
              className="form-control"
            />
          </div>
          <div className="form-group">
            <button
              onClick={(e) => {
                this.handleSubmit(e);
                this.modal2Open(e);
              }}
              type="button"
            >
              Save
            </button>
            <Modal
              show={this.state.modal2}
              handleClose={(e) => this.modal2Close(e)}
            >
              <h2>Modal 2 - Confirmation</h2>
            </Modal>
          </div>
        </Modal>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

When I click on the 'save' button from the modal, it should save and show a thank you/confirmation message in another modal.

How to deal with multiple modals in such a scenario? Is it something I can achieve it modifying the Modal.js? Can someone guide me on how to implement that in the shared example?


Solution

  • Instead of having 2 nested modals, why not have only one with two sub screens which you can navigate between via state?

    import React from "react";
    import ReactDOM from "react-dom";
    import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
    import Modal from "./components/Modal";
    
    import "./styles.css";
    
    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = {
          modal: false,
          modalScreen: 0,
          name: "",
          modalInputName: ""
        };
      }
    
      handleChange = (e) => {
        const { name, value } = e.target;
        this.setState({
          [name]: value
        });
      };
    
      handleSubmit = () => {
        this.setState({ name: this.state.modalInputName, modalScreen: 1 });
      };
    
      modalOpen = () => {
        this.setState({ modal: true });
      };
    
      modalClose = () => {
        this.setState({
          modalInputName: "",
          modal: false,
          modalScreen: 0
        });
      };
    
      render() {
        const { name, modal, modalScreen } = this.state;
        return (
          <div className="App">
            <h1>Hello!! {name}</h1>
            <button onClick={this.modalOpen}>Open Modal</button>
            <Modal show={modal} handleClose={(e) => this.modalClose(e)}>
              {modalScreen === 0 && (
                <>
                  <h2>Hello Modal</h2>
                  <div className="form-group">
                    <label>Enter Name:</label>
                    <input
                      type="text"
                      value={this.state.modalInputName}
                      name="modalInputName"
                      onChange={(e) => this.handleChange(e)}
                      className="form-control"
                    />
                  </div>
                  <div className="form-group">
                    <button onClick={this.handleSubmit} type="button">
                      Save
                    </button>
                  </div>
                </>
              )}
              {modalScreen === 1 && (
                <>
                  <h2>Modal 2 - Confirmation</h2>
                </>
              )}
            </Modal>
          </div>
        );
      }
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    Edit Simple Modal Box with React (forked)