“警告:react-modal:App 元素未定义。请使用 `Modal.setAppElement(el)` 或设置 `appElement=el`”
Posted
技术标签:
【中文标题】“警告:react-modal:App 元素未定义。请使用 `Modal.setAppElement(el)` 或设置 `appElement=el`”【英文标题】:"Warning: react-modal: App element is not defined. Please use `Modal.setAppElement(el)` or set `appElement=el`"“警告:react-modal:App 元素未定义。请使用 `Modal.setAppElement(el)` 或设置 `appElement=el`” 【发布时间】:2018-06-24 11:04:11 【问题描述】:如何使用 react-modal 包在 React 应用程序的控制台中修复此警告:
警告:react-modal:App 元素未定义。请使用
Modal.setAppElement(el)
或设置appElement=el
我还没有成功弄清楚el
应该是什么。
上下文: 在我的 App.js 根组件文件中:
...
import Modal from 'react-modal';
...
class App extends Component
...
render()
...
<Modal
className="modal"
overlayClassName="overlay"
isOpen=foodModalOpen
onRequestClose=this.closeFoodModal
contentLabel="Modal"
>
...
...
表示代码未显示。
一切正常,但是当打开 Modal 时,我的控制台中会出现以下警告:
index.js:2177 警告:react-modal:App 元素未定义。请使用
Modal.setAppElement(el)
或设置appElement=el
。这是必需的,以便屏幕阅读器在打开模式时看不到主要内容。不推荐,但您可以通过设置ariaHideApp=false
选择退出。
在react-modal docs 中,我只能找到以下内容:
应用元素 app 元素允许您指定应隐藏的应用程序部分(通过 aria-hidden),以防止屏幕阅读器等辅助技术读取模态内容之外的内容。
如果你在做服务器端渲染,你应该使用这个属性。
可以通过以下方式指定:
DOMElement
Modal.setAppElement(appElement);
query selector - uses the first element found if you pass in a class.
Modal.setAppElement('#your-app-element');
不幸的是,这没有帮助!
我不知道el
应该代表什么。
以下是我尝试添加到我的模态组件的许多属性变体中的一些:
`appElement=el`,
`appElement="root"` where `root` is the id that my App component is injected into
`appElement='root'`
`appElement="div"`,
`appElement=<div>`,
`appElement="div"`
我还尝试从src/index.js
内部调用Modal.setAppElement('root');
,其中root
是我的App
组件注入的根元素,而index.js 就是我这样做的地方。
【问题讨论】:
Sheryl 的回答是正确的——但请注意,“el”通常指的是 ref,是“element”的缩写。 【参考方案1】:将ariaHideApp=false
添加到Modal
属性。
这应该有效:
<Modal isOpen=!!props.selectedOption
onRequestClose=props.clearSelectedOption
ariaHideApp=false
contentLabel="Selected Option"
>
</Modal>
【讨论】:
来自官方文档:不推荐,但可以设置ariaHideApp=false
退出。【参考方案2】:
部分解决方案在react-modal issue #133:中给出
The problem lies here: 取决于它何时评估 react-modal@1.6.5:/lib/helpers/ariaAppHider.js#L1:
document.body 还不存在,它将解析为undefined || null
。
如果Modal.setAppElement()
是用null
调用的,或者根本不调用<script />
放在<head />
上(同上)。
如果使用不匹配任何结果的selector
调用,也可能会发生这种情况。
解决方案:
浏览器渲染:
@yachaka snippet 通过在放置<Modal />
之前定义元素来防止这种行为:
componentWillMount()
Modal.setAppElement('body');
@ungoldman answer,如果你不想依赖`setAppElement':
将捆绑的应用程序JS注入
<body>
而不是<head>
。 虽然理想情况下react-modal
应该等到 DOM 加载后尝试附加到document.body
。
服务器端:
如果在服务器端呈现,您必须在需要模态脚本之前提供
document.body
(在这种情况下,最好使用setAppElement()
)。
更新: react docs 已更新以包含上述信息,因此对于遇到此问题的用户来说,它们现在应该更清楚了。react-modal issue #567: 将信息(来自上面链接的问题 #133)添加到文档中。
【讨论】:
如果模态仅在组件中使用,是否可以安装它以使覆盖层仅覆盖该组件 - 而不是该组件的父/祖父母?我试了一下,好像不行,又回到了全屏。 由于 componentWillMount() 已被弃用,因此有一个新的解决方案会很有用。我找不到。【参考方案3】:像这样在你的模态中包含appElement=document.getElementById('app')
<Modal
className="modal"
appElement=document.getElementById('app')
>
如果应用程序是您在 index.html 中加载反应的中心,它将 100% 工作。
【讨论】:
由于getElementById
可以为空,您可能需要回退以确保类型安全。
@MoBeigi appElement=document.getElementById('root') || undefined
似乎就够了【参考方案4】:
这是我的 TypeScript Modal
组件,它包装了 react-modal
v3.8.1:
import React from 'react'
import ReactModal from 'react-modal'
interface Props
isOpen: boolean
ariaLabel?: string
const Modal: React.FC<Props> = (
children,
ariaLabel = 'Alert Modal',
isOpen,
) => (
<ReactModal
appElement=document.getElementById('root') as HTMLElement
ariaHideApp=process.env.NODE_ENV !== 'test'
isOpen=isOpen
contentLabel=ariaLabel
testId="modal-content"
>
children
</ReactModal>
)
export default Modal
在带有state = isOpen: true
的组件中使用:
<Modal isOpen=this.state.isOpen>
<p>
Modal Content here…
</p>
<button onClick=() => this.setState( isOpen: false ) >Okay</button>
</Modal>
【讨论】:
它也适用于 react typescript 项目。所以,赞成。【参考方案5】:如果在运行测试(我们正在运行 Jest)时收到 Warning: react-modal: App element is not defined...
错误,您可以通过将以下内容添加到您的测试文件来抑制警告:
import ReactModal from 'react-modal';
ReactModal.setAppElement('*'); // suppresses modal-related test warnings.
【讨论】:
【参考方案6】:最短的解决方案是添加appElement=document.getElementById("hereIsYourRootElementId")
它让 react-modal 知道你的根元素在哪里。
【讨论】:
【参考方案7】:就放这个Modal.setAppElement('#root')
这将解决警告。来自公用文件夹 index.html 内部的根元素。
【讨论】:
【参考方案8】:作为参考,因为这对我来说很痛苦,如果你正在做 s-s-r,请使用以下代码来防止服务器端错误:
if (typeof(window) !== 'undefined')
ReactModal.setAppElement('body')
你可以把它放在componentDidMount()
任何你使用模态的地方,或者我把它放在一个自定义的模态组件中,这样它既好又干。
【讨论】:
react-modal
已在上游修复,所以这应该不再是问题了。
不是,我更新了模块但仍然收到此警告。【参考方案9】:
您需要在根元素 ID 之前添加 #。
import React from 'react';
import Modal from 'react-modal';
Modal.setAppElement('#root');
const OptionModal = (props) => (
<Modal
isOpen=!!props.selectedOption
contentLabel='this is the selected option'
>
<h3>Selected Option</h3>
props.selectedOption && <p>props.selectedOption</p>
<button onClick = props.handleCloseOptionModal>Close</button>
</Modal>
);
export default OptionModal;
这里是参考: http://reactcommunity.org/react-modal/accessibility/
【讨论】:
【参考方案10】:如果您在使用“react-testing-library”进行测试时收到警告,这里有一个解决方案: https://github.com/reactjs/react-modal/issues/576#issuecomment-524644035
使用 react-testing-library (https://testing-library.com/) 我摆脱了这个警告:
import Modal from "react-modal";
const container = render(<MyComponent />);
Modal.setAppElement(container);
.... // to the testing, use Modal
或者,如果你想直接测试模态组件:
const container, rerender render(<MyModalComponent isOpen=false />);
Modal.setAppElement(container);
// now the appElement is set we can show the modal component
rerender(<MyModalComponent isOpen=false />);
.... // to the testing
【讨论】:
【参考方案11】:删除此属性 类名=“模态” 然后再次运行
【讨论】:
以上是关于“警告:react-modal:App 元素未定义。请使用 `Modal.setAppElement(el)` 或设置 `appElement=el`”的主要内容,如果未能解决你的问题,请参考以下文章