Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJs: Wrap Semantic UI Modal using Portal "pattern"

I'm trying to wrap Semantic UI Modal component using portal approach described here

Here is my take at it http://jsfiddle.net/mike_123/2wvfjpy9/ I'm running into issue though, when obtaining a DOM reference and Rendering new markup into it there seem to be old reference still maintained.

render: function() {
    return <div className="ui modal"/>; <-- the idea at first was to only return <div/>
},

...

        React.render(<div > <----------- originally this element had className="ui modal", but this.node doesn't seem to overtake the original node reference
                    <i className="close icon"></i>
                    <div className="header">test</div>
                    <div className="content">
                        {props.children}
                    </div>
                </div>, <----------- 
                this.node);

Any pointers how fix this test case http://jsfiddle.net/mike_123/2wvfjpy9/

like image 250
mike123 Avatar asked Dec 08 '22 04:12

mike123


1 Answers

You will lose correct vertical positioning and probably animations with approaches mentioned above.

Instead, you can just place your modal's component inside your app's root component and call .modal() with detachable: false. With this option, semantic wouldn't make any DOM manipulations and you won't lose your React DOM event listeners.

Example using Webpack/Babel:

import React, { Component } from 'react'
import $ from 'jquery'

if (typeof window !== 'undefined') {
  window.jQuery = $
  require('semantic-ui/dist/semantic.js')
}

class App extends Component {
  state = {
    showModal: false
  }

  _toggleModal = (e) => {
    e.preventDefault()
    this.toggleModalState()
  }

  toggleModalState = () => {
      this.setState({ showModal: !this.state.showModal })  
  }

  render() {
    return (
      <div>
        <a href="" onClick={this._toggleModal}></a>
        {this.state.showModal
          ? <Modal toggleModalState={this.toggleModalState}/>
          : ''}
      </div>
    ) 
  }
}

class Modal extends Component {
  componentDidMount() {   
    $(this.modal)
      .modal({ detachable: false })
      .modal('show')
  }

  componentWillUnmount() {   
    $(this.modal).modal('hide')
  }

  _close = (e) {
    e.preventDefault()
    alert("Clicked")
    this.props.toggleModalState()
  }

  render() {
    return (
      <div ref={(n) => this.modal = n} className="ui modal">
        <div class="content">
          <a onClick={this._close} href="">Click Me</a>
        </div>
      </div>
    )
  }
 }
like image 82
khrykin Avatar answered Jan 19 '23 11:01

khrykin