23 votes

Ajouter une classe à la balise HTML <body> avec React ?

Je crée une modale dans mon projet React qui nécessite qu'une classe soit ajoutée au corps lorsque la modale est ouverte et supprimée lorsqu'elle est fermée.

Je pourrais le faire à l'ancienne, à la manière de jQuery, en exécutant du javascript vanille qui ajoute/supprime une classe, mais cela ne ressemble pas à la philosophie normale de React.

Dois-je plutôt définir setState sur mon composant de niveau supérieur pour indiquer si la fenêtre modale est ouverte ou fermée ? Même si je faisais cela, comme c'est rendu dans la div sur la page, c'est toujours un effet de bord pour éditer l'élément body donc il y a un avantage pour ce câblage supplémentaire ?

31voto

Sam Logan Points 685

TL;DR utilice document.body.classList.add y document.body.classList.remove

J'aurais deux fonctions qui font basculer un élément d'état pour afficher/masquer la fenêtre modale dans votre composant externe.

À l'intérieur de ces fonctions, j'utiliserais la fonction document.body.classList.add y document.body.classList.remove pour manipuler le corps de la classe en fonction de l'état de la fenêtre modale, comme ci-dessous :

openModal = (event) => {
  document.body.classList.add('modal-open');
  this.setState({ showModal: true });
}
hideModal = (event) => {
  document.body.classList.remove('modal-open');
  this.setState({ showModal: false });
}

8voto

Lukas Kral Points 427

Avec la nouvelle version de React (16.8), ce problème peut être résolu avec crochets :

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

puis, dans la composante

export const Sidebar = ({position = 'left', children}) => {
    useBodyClass(`page--sidebar-${position}`);
    return (
        <aside className="...">
            {children}
        </aside>
    );
};

0voto

JustinToh Points 1

Comme @brian l'a mentionné, essayez d'avoir un composant conteneur de haut niveau qui entoure vos autres composants. (en supposant que vous n'utilisez pas redux dans votre application)

Dans ce composant de premier niveau :

  1. Ajouter un état booléen (ex. modalOpen ) pour faire basculer la classe CSS
  2. Ajouter des méthodes (ex. handleOpenModal & handleCloseModal ) pour modifier l'état booléen.
  3. Passez les méthodes créées ci-dessus en tant qu'accessoires dans votre <Modal /> composante

-3voto

swyx Points 88

ReactJS dispose d'un composant React Modal officiel, je l'utiliserais donc : https://github.com/reactjs/react-modal

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X