Taio
Taio

Reputation: 3734

open a html modal programmatically in React

I have this two elements a button and a dialog

<dialog className='w-11/12 shadow-none rounded-tl-md rounded-tr-md lg:rounded-lg absolute'>wqdwe</dialog>

<button className=" px-6 py-2 rounded absolute mt-12 ml-12" onClick={} >Click</button>

How can I open the dialog on clicking the button in React

constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  showModals(){
this.myRef.showModal();
  }
  componentDidMount() {
   //this.showModals()
  }

EDIT: I am trying to access the .showModal() method in the dialog according to MDN https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog. How can I do that, I need the dimmed background feature when the modal is opened.

Upvotes: 1

Views: 2137

Answers (2)

A. Ecrubit
A. Ecrubit

Reputation: 609

You do not need componentDidMount nor useRef with the state and using the props open of the dialog you can show it conditionally.

  1. first solution using isOpen is the state

class Modal extends React.Component {
  constructor(props) {
    super(props);
  }
  
   render() {
    return (
      <dialog style={{width: "80%", height: "80%", marginTop: 10, backgroundColor: '#eee'}}
        open={this.props.open}
        >
        <p>Greetings, one and all!</p>
      </dialog>
    );
  }
}

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isOpen: false
    };
  }
  
  switchModal = (prevState) => {
    this.setState((prevState, props) => {
      return { isOpen: !prevState.isOpen }
    });
  }

 render() {
    return (
      <div>
        <button onClick={this.switchModal}>
          {this.state.isOpen ? 'Close' : 'Open'} Modal 
        </button>
        <br/>
        <Modal open={this.state.isOpen}/>
      </div>
    );
  }
}

React.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js"></script>
<div id="root"></div>

  1. second solution using native showModal method. With this method you can use the css property dialog::backdrop.

class Modal extends React.Component {
  constructor(props) {
    super(props);
  }
 
   render() {
    return (
      <dialog id='modal' style={{width: "80%", height: "80%", marginTop: 10, backgroundColor: '#eee'}}
        >
        <p>Greetings, one and all!</p>
        <button onClick={this.props.closeModal}>
          Close Modal 
        </button>
      </dialog>
    );
  }
}

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      isOpen: false
    };
  }
  
  switchModal = (prevState) => {
    this.setState((prevState, props) => {
      if(!prevState.isOpen) {
        document.getElementById('modal').showModal()
      } else {
        document.getElementById('modal').close()
      }
      return { isOpen: !prevState.isOpen }
    });
  }

 render() {
    return (
      <div>
        {!this.state.isOpen && <button onClick={this.switchModal}>
          Open Modal 
        </button>}
        <br/>
        <Modal 
          closeModal={this.switchModal}
          />
      </div>
    );
  }
}

React.render(<App />, document.getElementById('root'));
dialog {
  height: 80%;
  width: 80%
}

dialog::backdrop {
  background: rgba(255,0,0,.25);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.min.js"></script>
<div id="root"></div>

Upvotes: 2

Tom Oakley
Tom Oakley

Reputation: 6403

You can use the React state API to show and hide components based on actions taken elsewhere in the code.

class MyComponent extends React.Component {

  constructor() {
    this.state = {
      isDialogVisible: false
    }
  }

  handleClick = () => {
    this.setState({ isDialogVisible: !this.state.isDialogVisible })
  }

  render() {
    const { isDialogVisible } = this.state
    return (
      <div>
        <Button onClick={this.handleClick}>{isDialogVisible ? 'Hide' : 'Show'} dialog</Button>
        {this.state.isDialogVisible && <Dialog />}
      </div>
   )
 }
}

Upvotes: 0

Related Questions