"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