31

如何使用 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 文档中,我只能找到以下内容:

App 元素 app 元素允许您指定应用程序中应隐藏的部分(通过 aria-hidden),以防止屏幕阅读器等辅助技术读取模态内容之外的内容。

如果你在做服务器端渲染,你应该使用这个属性。

可以通过以下方式指定:

DOM元素
Modal.setAppElement(appElement);
query selector - uses the first element found if you pass in a class.
Modal.setAppElement('#your-app-element');

不幸的是,这没有帮助!我无法弄清楚el应该代表什么。

以下是我尝试添加到我的 Modal 组件的许多属性变体中的一些:

`appElement={el}`,  
`appElement="root"` where `root` is the id that my App component is injected into   
`appElement={'root'}`   
`appElement="div"`,   
`appElement={<div>}`,   
`appElement={"div"}`  

我也尝试过从Modal.setAppElement('root');inside调用,我的组件被注入 的根元素src/index.js在哪里,而 index.js 就是我这样做的地方。rootApp

4

11 回答 11

36

添加 ariaHideApp={false}Modal属性。

这应该有效:

<Modal isOpen={!!props.selectedOption}
    onRequestClose={props.clearSelectedOption}
    ariaHideApp={false}
    contentLabel="Selected Option"
    >
</Modal>
于 2018-05-31T13:05:23.753 回答
25

react-modal issue #133中给出了一些解决方案:

问题出在这里: 取决于它何时评估 react-modal@1.6.5:/lib/helpers/ariaAppHider.js#L1:

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

解决方案:

浏览器渲染:

@yachaka 片段通过在放置之前定义元素来防止这种行为<Modal />

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

@ungoldman 回答,如果您不想依赖 `setAppElement':

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

服务器端:

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


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

于 2018-01-15T20:38:13.767 回答
13

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

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

如果应用程序是您在 index.html 中加载反应的中心,它将 100% 工作。

于 2018-09-02T00:41:00.303 回答
7

这是我包装v3.8.1的 TypeScriptModal组件:react-modal

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>
于 2019-02-13T21:47:47.037 回答
4

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

import ReactModal from 'react-modal';
ReactModal.setAppElement('*'); // suppresses modal-related test warnings.
于 2019-03-25T13:18:20.923 回答
4

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

它让 react-modal 知道你的根元素在哪里。

于 2019-11-04T10:46:15.377 回答
3

就放这个
Modal.setAppElement('#root')

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

于 2020-10-31T06:14:00.350 回答
2

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

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

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

于 2018-04-22T19:42:39.320 回答
1

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

于 2018-10-02T14:44:44.470 回答
0

如果您在使用“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
于 2019-08-25T16:49:06.987 回答
-3

删除此属性 className="modal" 并再次运行

于 2020-11-13T07:33:15.520 回答