使用React将类添加到HTML <body>标记中?

Eva*_*nss 24 html5 classname reactjs

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

我可以通过运行一些添加/删除类的vanilla javascript来实现旧的jQuery方式,但这并不像普通的React哲学那样.

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

Sam*_*gan 36

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

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

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

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


Luk*_*ral 11

使用新的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]
    );
}
Run Code Online (Sandbox Code Playgroud)

然后,在组件中

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

  • 16.8,不是 16.9 :) (2认同)

Boj*_*tic 8

其实你不需要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>
Run Code Online (Sandbox Code Playgroud)

  • 我还会在 useEffect 挂钩中添加一个清理函数 `return () =&gt; document.body.classList.remove('modal-open')` 。 (5认同)