使用 React 在 HTML <body> 标签中添加一个类?

IT技术 html reactjs classname
2021-05-21 07:08:38

我正在我的 React 项目中创建一个模态,当模态打开时需要将一个类添加到主体中,并在它关闭时移除。

我可以通过运行一些添加/删除类的 vanilla JavaScript 来使用旧的 jQuery 方式来做到这一点,但这感觉不像是正常的 React 哲学。

我应该在我的顶级组件上使用 setState 来说明模态是打开还是关闭?即使我这样做了,因为它被渲染到页面上的 div 中,它仍然是编辑 body 元素的副作用,所以这种额外的布线有什么好处吗?

4个回答

TL;DR使用document.body.classList.adddocument.body.classList.remove

我将有两个函数来切换状态以显示/隐藏外部组件中的模态。

在这些函数中,我将使用document.body.classList.adddocument.body.classList.remove方法来操作依赖于模态状态的主体类,如下所示:

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

使用新的 React (16.8) 这可以通过钩子解决

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

然后,在组件中

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

其实你不需要2个功能来打开和关闭,你可以使用 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>

就像@brian 提到的那样,尝试使用一个顶级容器组件来包裹您的其他组件。(假设你没有在你的应用中使用 redux)

在这个顶级组件中:

  1. 添加一个布尔状态(例如modalOpen)来切换 CSS 类
  2. 添加方法(例如handleOpenModal& handleCloseModal)来修改布尔状态。
  3. 将上面创建的方法作为道具传递到您的<Modal />组件中