Describe the bug
I'd like to add a story of my Modal component which is made by ReactDOM.createPortal .
the modal container is <div id="modal-root"></div>
added by me in index.html .
but when I write story like this:
storiesOf('atoms/modal', module)
.addDecorator(withKnobs)
.add('Modal', () => (
<Modal
isOpen={true}
onRequestClose={action('onRequestClose')}
>
<div>modal</div>
</Modal>
))
「Target container is not a DOM element」error happened.
I think it's because there is no modal-root div in Storybook UI?
How can I fix it?
To Reproduce
see above
Screenshots
Code snippets
this is my Modal code for short:
const modalRoot = document.getElementById('modal-root')
class Modal extends React.Component {
constructor(props) {
super(props)
this.el = document.createElement('div')
}
componentDidMount() {
modalRoot.appendChild(this.el)
}
componentWillUnmount() {
modalRoot.removeChild(this.el)
}
handleClickBackDrop = event => {
this.props.onRequestClose(event)
}
render() {
const { isOpen, children } = this.props
if (!isOpen) {
return null
}
const modalUI = (
<BackDropWrapper
onClick={this.handleClickBackDrop}
>
<ModalWrapper>
{children}
</ModalWrapper>
</BackDropWrapper>
)
return ReactDOM.createPortal(modalUI, modalRoot)
}
}
System:
Since the const modalRoot = document.getElementById('modal-root')
is called statically, you need to generate the <div id="modal-root">
before the Modal
component is imported. I can suggest creating this div in config.js
before loading the stories.
Something like this:
// config.js
const modalRoot = document.createElement('div');
modalRoot.setAttribute('id', 'modal-root');
document.body.append(modalRoot);
@igor-dv Thank you your suggestion worked.
Most helpful comment
Since the
const modalRoot = document.getElementById('modal-root')
is called statically, you need to generate the<div id="modal-root">
before theModal
component is imported. I can suggest creating this div inconfig.js
before loading the stories.Something like this: