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/
Khanetor answered this question thoroughly and correctly, I just want to contribute one additional tidbit about how to position the Modal. It would be best as a comment, but unfortunately, I don't have the reputation to do so.
Anyways, the first child element of the Portal element needs to be positioned absolutely in order to make the dimmer and resulting modal sit on top of the page content rather than get put beneath it.
First, add
style={position:'absolute'}
to thePortal
declaration inModal
's render method so the dimmer gets set at the top of the page. You end up with:Next, set the
InnerModal
's position torelative
and decide on a distance from the top of the screen. I used an eighth (or 0.125) of the browser's viewport and got:With those edits made, I've finally got some working modals in React! Hope this is helpful to someone else running into some of the same issues I've been.
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()
withdetachable: 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:
When you call
this.$modal.modal('show')
, it will actually restructure your DOM, and React will not be happy about it. Plus, if you try to put control in your modal, the control will not work.What you should do is to
React.render
an already shown modal, i.e. a modal with markup as if$('.ui.modal').modal('show')
has been called.Here is my attempt using "React-Portal" to help with rendering a react component at body level. You can still use your method if you prefer.
Notice that my modal has already been rendered in the markup.
You can then consume the modal as below:
With this you don't have to hack your way into DOM manipulation with jQuery, and the control in the modal (button, link, etc, to invoke functions) still works.
Hope this help!