Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「Target container is not a DOM element」error happened when using ReactDOM.createPortal method #4604

Closed
kidmysoul opened this issue Oct 29, 2018 · 2 comments

Comments

@kidmysoul
Copy link

kidmysoul commented Oct 29, 2018

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
2018-10-29 15 17 08

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:

  • Framework: react
  • Addons: addon-knobs
  • Version: 4.0.0-alpha.3
@igor-dv
Copy link
Member

igor-dv commented Oct 29, 2018

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);

@kidmysoul
Copy link
Author

@igor-dv Thank you your suggestion worked.

@igor-dv igor-dv closed this as completed Oct 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants