"警告:react-modal:未定义App元素.请使用`Modal.setAppElement(el)`或设置`appElement = {el}`"

She*_*man 12 javascript reactjs react-modal web-accessibility

如何使用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"
    >
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

react-modal文档中,我可以找到以下内容:

应用程序元素应用程序元素允许您指定应隐藏的应用程序部分(通过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应该代表什么.

以下是我尝试添加到我的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"}`  
Run Code Online (Sandbox Code Playgroud)

我也打过电话Modal.setAppElement('root');,从里面src/index.js,那里root是我的根元素App成分注入,并index.js是我做的.

She*_*man 15

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

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

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

解决方案:

浏览器渲染:

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

componentWillMount() {
    Modal.setAppElement('body');
}
Run Code Online (Sandbox Code Playgroud)

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

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

服务器端:

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


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

  • 既然 componentWillMount() 已被弃用,那么拥有一个新的解决方案将会很有用。我找不到一个。 (2认同)

amr*_*tri 9

添加 ariaHideApp={false}Modal属性。

这应该工作:

<Modal isOpen={!!props.selectedOption}
    onRequestClose={props.clearSelectedOption}
    ariaHideApp={false}
    contentLabel="Selected Option"
    >
</Modal>
Run Code Online (Sandbox Code Playgroud)

  • 最好按照它所说的去做,因为这样可以避免警告所指的可访问性问题。 (6认同)
  • 根据官方文档:不推荐,但您可以通过设置 ariaHideApp={false} 来选择退出。 (3认同)

Joe*_*dee 8

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

import ReactModal from 'react-modal';
ReactModal.setAppElement('*'); // suppresses modal-related test warnings.
Run Code Online (Sandbox Code Playgroud)


小智 5

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

<Modal
className="modal"
appElement={document.getElementById('app')}
>
Run Code Online (Sandbox Code Playgroud)

如果应用是您在index.html中的中心位置,那么它将100%工作。

  • @MoBeigi `appElement={document.getElementById('root') || 未定义}`似乎就足够了 (5认同)

Bea*_*ith 5

这是我的 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
Run Code Online (Sandbox Code Playgroud)

在组件中使用state = { isOpen: true }

<Modal isOpen={this.state.isOpen}>
  <p>
    Modal Content here…
  </p>
  <button onClick={() => { this.setState({ isOpen: false }) }}>Okay</button>
</Modal>
Run Code Online (Sandbox Code Playgroud)