Describe el error
Me gustaría agregar una historia de mi componente Modal que está hecho por ReactDOM.createPortal.
el contenedor modal es <div id="modal-root"></div>
agregado por mí en index.html.
pero cuando escribo una historia como esta:
storiesOf('atoms/modal', module)
.addDecorator(withKnobs)
.add('Modal', () => (
<Modal
isOpen={true}
onRequestClose={action('onRequestClose')}
>
<div>modal</div>
</Modal>
))
「El contenedor de destino no es un elemento DOM」 ocurrió un error.
Creo que es porque no hay un div de raíz modal en la interfaz de usuario de Storybook.
¿Cómo puedo arreglarlo?
Reproducir
véase más arriba
Capturas de pantalla
Fragmentos de código
este es mi código modal para abreviar:
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)
}
}
Sistema:
Dado que el const modalRoot = document.getElementById('modal-root')
se llama estáticamente, debe generar el <div id="modal-root">
antes de que se importe el componente Modal
. Puedo sugerir crear este div en config.js
antes de cargar las historias.
Algo como esto:
// config.js
const modalRoot = document.createElement('div');
modalRoot.setAttribute('id', 'modal-root');
document.body.append(modalRoot);
@ igor-dv Gracias, su sugerencia funcionó.
Comentario más útil
Dado que el
const modalRoot = document.getElementById('modal-root')
se llama estáticamente, debe generar el<div id="modal-root">
antes de que se importe el componenteModal
. Puedo sugerir crear este div enconfig.js
antes de cargar las historias.Algo como esto: