使用 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 () => 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.add
和 document.body.classList.remove
我将有两个函数来切换一个状态以在您的外部组件中显示/隐藏模式。
在这些函数中,我将使用document.body.classList.add
和document.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 传递到您的 <Modal />
组件中
【讨论】:
以上是关于使用 React 向 HTML <body> 标签添加一个类?的主要内容,如果未能解决你的问题,请参考以下文章