Estoy creando un modal en mi proyecto React que requiere que se agregue una clase al cuerpo cuando el modal está abierto y se elimina cuando está cerrado.
Podría hacer esto a la antigua usanza de jQuery ejecutando JavaScript estándar que agrega/elimina una clase, sin embargo, esto no se siente como la filosofía normal de React.
¿Debería establecer Estado en mi componente de nivel superior para decir si el modal está abierto o cerrado? Incluso si hiciera esto, como se representa en el div en la página, todavía es un efecto secundario editar el elemento del cuerpo, entonces, ¿hay algún beneficio para este cableado adicional?
TL;DR use document.body.classList.add y document.body.classList.remove
Tendría dos funciones que alternan una parte del estado para mostrar/ocultar el modal dentro de su componente externo.
Dentro de estas funciones, usaría los métodos document.body.classList.add y document.body.classList.remove para manipular la clase del cuerpo dependiendo del estado del modal como se muestra a continuación:
openModal = (event) => { document.body.classList.add('modal-open'); this.setState({ showModal: true }); } hideModal = (event) => { document.body.classList.remove('modal-open'); this.setState({ showModal: false }); }Con el nuevo React (16.8) esto se puede resolver con ganchos :
import {useEffect} from 'react'; const addBodyClass = className => document.body.classList.add(className); const removeBodyClass = className => document.body.classList.remove(className); export default function useBodyClass(className) { useEffect( () => { // Set up className instanceof Array ? className.map(addBodyClass) : addBodyClass(className); // Clean up return () => { className instanceof Array ? className.map(removeBodyClass) : removeBodyClass(className); }; }, [className] ); }entonces, en el componente
export const Sidebar = ({position = 'left', children}) => { useBodyClass(`page--sidebar-${position}`); return ( <aside className="..."> {children} </aside> ); };En realidad, no necesita 2 funciones para abrir y cerrar, puede usar document.body.classList.toggle
const [isOpen, setIsOpen] = useState(false) useEffect(() => { document.body.classList.toggle('modal-open', isOpen); },[isOpen]) <button onCLick={()=> setIsOpen(!isOpen)}>Toggle Modal</button>