#reactjs #leaflet #react-admin #react-leaflet
Вопрос:
Я использую React-admin для проекта, где для некоторых ресурсов я использую форму с вкладками, чтобы лучше организовать поля и входные данные. Я создал довольно простой пользовательский компонент карты на основе react-leaflet, который я использую в этих формах с вкладками.
Я столкнулся со странной проблемой, когда, когда карта находится не на первой вкладке, ее содержимое отображается некорректно. Создается впечатление, что карта «думает», что область просмотра намного меньше, чем она есть на самом деле. Перезагрузка страницы (или даже просто открытие инструментов разработчика в Chrome) приводит к повторному рендерингу страницы и заставляет карту вести себя правильно.
Чтобы лучше продемонстрировать, я создал этот простой проект Codesandbox. В нем есть пользовательский ресурс из учебника RA с двумя вкладками. Оба содержат экземпляр компонента map, но в то время как карта на первой вкладке сразу работает правильно, карта на второй вкладке отображается неправильно.
Признаюсь, я все еще новичок в этих вещах, поэтому вполне могу делать что-то не так, но я уже несколько часов ломаю голову над этим, и я хотел бы начать устранять возможных виновников.
Любая информация будет приветствоваться.
Заранее большое спасибо за ваше время.
Ответ №1:
Эта проблема много обсуждалась в SO. Если вы немного поищете, вы можете найти причину. На самом деле вам нужно сделать две вещи:
- используйте
setInterval
в сочетании сinvalidateSize
методом map при переключении вкладки, а затем очистите его при размонтировании компонента - используется
useEffect
для изменения масштаба карты и представления, поскольку они неизменяемы.
ИТАК, поскольку вы используете react-leaflet версии 2.7.x, вам необходимо взять экземпляр карты, используя ссылку:
const mapRef = useRef();
useEffect(() => {
if (!mapRef.current) return;
const map = mapRef.current.leafletElement;
const mapZoom = zoom || defaultZoom;
let intervalInstance;
if (!center amp;amp; marker) {
map.setView(marker, mapZoom);
intervalInstance = setInterval(() => map.invalidateSize(), 100);
} else if (!center) {
map.setView([0.0, 0.0], mapZoom);
}
map.setZoom(mapZoom);
return () => clearInterval(intervalInstance);
}, []);
<LeafletMap
ref={mapRef}
center={marker}
zoom={defaultZoom}
className={classes.leafletContainer}
>
Комментарии:
1. Хороший обзор! Если возможно, сделайте недействительным значение после отображения вкладки карты, а не с помощью setInterval.
2. Очень признателен за исправления и обновленную песочницу. Если вы не возражаете, если я спрошу, вопрос, о котором вы упоминаете, обсуждался на SO, относится ли этот конкретный вопрос к Leaflet или к более общему ReactJS?
3. Это связано с листовкой