"Warning: react-modal: App element is not defined. Please use `Modal.setAppElement(el)` or set `app



如何使用反应模态包在 React 应用程序的控制台中修复此警告:

警告:反应模式:未定义应用程序元素。请使用Modal.setAppElement(el)或设置appElement={el}

我还没有成功地弄清楚el应该是什么。

上下文: 在我的应用程序中.js根组件文件中:

...
import Modal from 'react-modal';
...
class App extends Component {
...
render(){
...  
<Modal
className="modal"
overlayClassName="overlay"
isOpen={foodModalOpen}
onRequestClose={this.closeFoodModal}
contentLabel="Modal"
>
...
}
}

其中...表示未显示代码。

一切正常,但是当模式打开时,我的控制台中会出现以下警告:

index.js:2177 警告:反应模式:未定义应用元素。请使用Modal.setAppElement(el)或设置appElement={el}。这是必需的,以便屏幕阅读器在打开模式时看不到主要内容。不建议这样做,但您可以通过设置ariaHideApp={false}来选择退出。

在反应模态文档中,我能找到的只有以下内容:

应用元素 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 是我这样做的地方。

ariaHideApp={false}添加到Modal属性。

这应该有效:

<Modal isOpen={!!props.selectedOption}
onRequestClose={props.clearSelectedOption}
ariaHideApp={false}
contentLabel="Selected Option"
>
</Modal>

反应模态问题 #133 中给出了一些解决方案:

问题就在这里: 根据它何时计算 react-modal@1.6.5:/lib/helpers/ariaAppHider.js#L1:

  • document.body 尚不存在,它将解析为undefined || null
  • 如果使用null调用Modal.setAppElement(),或者根本不调用放置在<head />上的<script />(与上述相同)。
  • 如果使用与任何结果都不匹配的selector调用,也可能发生这种情况。

解决 方案:

浏览器渲染:

@yachaka代码段通过在放置<Modal />之前定义元素来防止此行为:

componentWillMount() {
Modal.setAppElement('body');
}

@ungoldman答案,如果你不想依赖'setAppElement':

捆绑的应用程序 JS 注入<body>而不是<head>
尽管理想情况下react-modal应该等到 DOM 加载后再尝试附加到document.body.

服务器端:

如果在服务器端渲染,则必须在需要模态脚本之前提供一个document.body(在这种情况下,也许最好使用setAppElement())。


更新: React 文档已更新以包含上述信息,因此对于遇到此问题的用户来说,它们现在应该更清晰。
反应模式问题 #567:将信息(来自上面链接的问题 #133)添加到文档中。

只需像这样将appElement={document.getElementById('app')}包含在您的模态中

<Modal
className="modal"
appElement={document.getElementById('app')}
>

如果应用程序是索引的中心.html则它将 100% 工作,从 react 加载的位置。

这是我的TypeScriptModal组件,它包装了react-modalv3.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>

如果在运行测试时收到Warning: react-modal: App element is not defined...错误(我们正在运行 Jest),您可以通过向测试文件添加以下内容来禁止显示警告:

import ReactModal from 'react-modal';
ReactModal.setAppElement('*'); // suppresses modal-related test warnings.

只需输入这个
Modal.setAppElement('#root')

这将解决警告。来自公用文件夹索引.html内部的根元素。

最短的解决方案是添加
appElement={document.getElementById("hereIsYourRootElementId")}

它让反应模态知道你的根元素在哪里。

作为参考,由于这对我来说很痛苦,如果您正在执行 SSR,请使用以下代码来防止服务器端出现错误:

if (typeof(window) !== 'undefined') {
ReactModal.setAppElement('body')
}

你可以把它放在任何使用模态的地方componentDidMount()或者我把它放在一个自定义的模态组件中,所以它很好而且很干。

您需要在根元素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/

对于 Nextjs,我认为您可以通过在声明组件之前将以下内容添加到模态组件外部(可能在顶部)来解决此问题。

Modal.setAppElement('#__next')

如果您在使用"react-testing-library"进行测试时收到警告,这里有一个解决方案: https://github.com/reactjs/react-modal/issues/576#issuecomment-524644035

使用反应测试库(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

在 nextjs 中解决:这为我解决了,我只是在布局中的根主体中添加了一个 id,然后在模态中添加了一个appElement={document.getElementById("root")}

布局.js组件

<body suppressHydrationWarning={true} id='root'>
<div className='main-container col-12 d-flex flex-row h-100 w-100 col-12 justify-content-start align-items-start'>
<main className='col-10'>{children}</main>
</div>
</body>

一些组件

<Modal
isOpen={modalIsOpen}
onRequestClose={closeModal}
contentLabel='Book Modal'
appElement={document.getElementById("root")}
style={{
content: {
width: "850px",
height: "85vh",
margin: "auto",
padding: "0px",
border: "none",
overflow: "hidden",
},
}}
>
<h1>Content Of Modal Goes Here</h1>
</Modal>

删除此属性 类名称="模态" 并再次运行

最新更新