"Warning: response-modal: элемент приложения не определен. Используйте" Modal.setAppElement(el) "или установите` appElement = {el} `"

Как исправить это предупреждение в консоли приложения React с помощью пакетаact-modal:

Предупреждение: реакции-модал: элемент приложения не определен. Пожалуйста, используйте 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"
    >
    ...
  }
}

Где ... означает, что код не показан.

Все работает нормально, но когда модал открыт, в моей консоли появляется следующее предупреждение:

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"}'  

Я также пытался вызвать Modal.setAppElement('root'); изнутри src/index.js, где root является корневым элементом, в который вставлен мой компонент App, а index.js - то, где я это делаю.

Ответ 1

Некоторые решения приведены в реактивной проблеме № 133:

Проблема заключается здесь: В зависимости от того, когда он оценивает [email protected]: /lib/helpers/ariaAppHider.js#L1:

  • document.body еще не существует, и он будет преобразован в undefined || null.
  • если Modal.setAppElement() вызывается с помощью null или не вызывается вообще с помощью <script />, помещенного в <head /> (то же, что и выше).
  • Вероятно, это также может произойти, если вызывается с selector, который не соответствует никаким результатам.

Решения:

Рендеринг в браузере:

Фрагмент @yachaka предотвращает такое поведение, определяя элемент перед размещением <Modal />:

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

@ungoldman ответьте, если вы не хотите зависеть от 'setAppElement':

Вставьте JS связанного приложения в <body> вместо <head>.
Хотя в идеале react-modal должен дождаться загрузки DOM, чтобы попытаться подключиться к document.body.

на стороне сервера:

Если вы выполняете рендеринг на стороне сервера, вы должны предоставить document.body, прежде чем требовать модальный скрипт (возможно, в этом случае предпочтительнее использовать setAppElement()).


Обновление: Реактивная документация была обновлена и теперь содержит указанную выше информацию, поэтому теперь она должна быть более понятной для пользователей, сталкивающихся с этой проблемой.
реакция # 567: добавить информацию (из ссылки № 133, указанной выше) в документы.

Ответ 2

Добавьте атрибуты ariaHideApp={false} к Modal.

Это должно работать:

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

Ответ 3

Просто включите appElement={document.getElementById('app')} в свой модал вот так

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

Это будет работать на 100%, если приложение является вашим центральным элементом в index.html, откуда реагируют нагрузки.

Ответ 4

Для справки, поскольку для меня было больно, если вы выполняете SSR, используйте следующий код для предотвращения ошибок на стороне сервера:

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

Вы можете поместить это в componentDidMount() в любом месте, где вы используете модальный, или я помещаю его в специальный модальный компонент, чтобы он был красивым и сухим.

Ответ 5

Если при выполнении тестов появляется ошибка Warning: react-modal: App element is not defined... (у нас был Jest), вы можете отключить предупреждения, добавив в свой тестовый файл следующее:

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

Ответ 6

вам нужно добавить # перед идентификатором корневого элемента.

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/

Ответ 7

Это мой компонент 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>

Ответ 8

Если вы получите это предупреждение при тестировании с помощью "библиотеки-реагирования-тестирования", вот решение: 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