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

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

如何使用 react-modal 包在 React 应用程序的控制台中修复此警​​告:

Warning: react-modal: App element is not defined. Please use Modal.setAppElement(el) or set 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"
    >
    ...
  }
}

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

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

index.js:2177 Warning: react-modal: App element is not defined. Please use Modal.setAppElement(el) or set appElement={el}. This is needed so screen readers don't see main content when modal is opened. It is not recommended, but you can opt-out by setting ariaHideApp={false}.

react-modal docs 我能找到的是以下内容:

App Element The app element allows you to specify the portion of your app that should be hidden (via aria-hidden) to prevent assistive technologies such as screenreaders from reading content outside of the content of your modal.

If you are doing server-side rendering, you should use this property.

It can be specified in the following ways:

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

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':

Inject the bundled application JS into <body> instead of <head>.
Though ideally react-modal should wait until the DOM is loaded to try attaching to document.body.

服务器端:

If rendering on server-side, you must provide a document.body, before requiring the modal script (perhaps it should be preferable to use setAppElement() in this case).


更新react docs 已更新以包含上述信息,因此现在应该让用户 运行 更清楚地了解这个问题。
react-modal issue #567: 将信息(来自上面链接的问题 #133)添加到文档中。

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

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

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

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

这应该有效:

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

就像这样

在你的模式中包含 appElement={document.getElementById('app')}
<Modal
className="modal"
appElement={document.getElementById('app')}
>

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

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

这是我的 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>

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

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

如果您在使用 "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

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

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

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

这将解决警告。来自 public 文件夹 index.html.

内的根元素

删除这个属性 类名=“模态” 并再次 运行