问题
Im making a modal in my React project that requires a class to be added to the body when the modal is open and removed when it is closed.
I could do this the old jQuery way by running some vanilla javascript which adds / removes a class, however this doesnt feel like the normal React philosophy.
Should I instead setState on my top level component to say weather the modal is open or closed? Even if I did this, as its rendered into the div on the page its still a side-effect to edit the body element so is there any benefit for this extra wiring?
回答1:
TL;DR use document.body.classList.add
and document.body.classList.remove
I would have two functions that toggle a piece of state to show/hide the modal within your outer component.
Inside these functions I would use the document.body.classList.add
and document.body.classList.remove
methods to manipulate the body class dependant on the modal's state like below:
openModal = (event) => {
document.body.classList.add('modal-open');
this.setState({ showModal: true });
}
hideModal = (event) => {
document.body.classList.remove('modal-open');
this.setState({ showModal: false });
}
回答2:
With the new React (16.8) this can be solved with hooks:
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]
);
}
then, in the component
export const Sidebar = ({position = 'left', children}) => {
useBodyClass(`page--sidebar-${position}`);
return (
<aside className="...">
{children}
</aside>
);
};
回答3:
Like what @brian mentioned, try having a top-level container component that wraps around your other components. (assuming you're not using redux in your app)
In this top-level component:
- Add a boolean state (eg.
modalOpen
) to toggle the CSS class - Add methods (eg.
handleOpenModal
&handleCloseModal
) to modify the boolean state. - Pass the methods created above as props into your
<Modal />
component
回答4:
ReactJS has an official React Modal component, I would just use that: https://github.com/reactjs/react-modal
来源:https://stackoverflow.com/questions/47706903/add-a-class-to-the-html-body-tag-with-react