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

Posted

技术标签:

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

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

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

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

【问题讨论】:

拥有一个***容器而不是直接操作body标签可能会有所帮助。 我更喜欢some vanilla javascript,你可以在componentDidMount中添加类并在componentWillUnmount中删除,mousewheel是全局的而不是React philosophy,你仍然使用它 How to add or remove a className on event in ReactJS的可能重复 【参考方案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)

在这个***组件中:

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

【讨论】:

以上是关于使用 React 向 HTML <body> 标签添加一个类?的主要内容,如果未能解决你的问题,请参考以下文章

react中向组件内部动态传入标签(带参数)

使用gulp+Browserify构建React应用

将带有 jquery 的 html 模板转换为 React js

React中this指向常用的2种修正方式

head与body(新手向)

向“body”添加一个类