【问题标题】:Add a class to the HTML <body> tag with React?使用 React 向 HTML <body> 标签添加一个类?
【发布时间】:2018-05-22 06:13:33
【问题描述】:

我在我的 React 项目中制作了一个模态框,它需要在模态框打开时将一个类添加到正文中,并在它关闭时将其删除。

我可以通过运行一些添加/删除类的 vanilla JavaScript 来执行旧的 jQuery 方法,但这并不像正常的 React 哲学。

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

【问题讨论】:

  • 拥有一个顶级容器而不是直接操作body标签可能会有所帮助。
  • 我更喜欢some vanilla javascript,你可以在componentDidMount中添加类并在componentWillUnmount中删除,mousewheel是全局的而不是React philosophy,你仍然使用它

标签: html reactjs classname


【解决方案1】:

其实你不需要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>

【讨论】:

  • 将 isMobileOpen 替换为 isOpen:document.body.classList.toggle('modal-open', isOpen);
  • 我还会在 useEffect 挂钩中添加一个清理函数 return () =&gt; document.body.classList.remove('modal-open')
【解决方案2】:

使用新的 React (16.8) 可以通过 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]
    );
}

那么,在组件中

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

【讨论】:

  • 16.8,不是 16.9 :)
  • 这不会为我删除之前的导航正文类。挂载的每个页面组件只是将类添加到正文中
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    ReactJS 有一个官方的 React Modal 组件,我会使用它:https://github.com/reactjs/react-modal

    【讨论】:

      【解决方案5】:

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

      在这个顶级组件中:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-28
        • 2011-12-03
        • 1970-01-01
        • 2017-09-18
        • 1970-01-01
        • 2018-04-16
        • 2018-03-09
        相关资源
        最近更新 更多