Estoy trabajando con un mapa React + Leaflet y me doy cuenta de que el contenedor/los elementos del mapa se vuelven a renderizar cada vez que muestro o cierro un modal.
Creé una zona de pruebas para demostrar el problema, pero esto ocurre en otros lugares a lo largo de mi aplicación si los ejemplos adicionales ayudaran.
https://codesandbox.io/s/elegant-rain-01f9l?file=/src/App.js
Al leer publicaciones SO alternativas, como esta muy similar , reconozco que esto probablemente se deba a mis ganchos (por ejemplo, handleShow/setShow) que fuerzan a todo el componente a volver a renderizarse. El comportamiento no deseado se nota de la siguiente manera:
Si arrastra el mapa para que la ubicación actual quede fuera de la vista y abre un modal, forzamos la recarga de <LeafletControlGeocoder/> y <LocationMarker/> . Esto es evidente porque el mapa vuelve a desplazarse a la ubicación actual y aparece un nuevo "icono de búsqueda" en la parte superior derecha del mapa.
Pasos para replicar:
* Si nota un problema en el entorno limitado relacionado con react-bootstrap/Modal, simplemente actualice la dependencia a la última versión (icono de actualización); este es un problema extraño del entorno limitado, pero no está relacionado con mi pregunta.
El problema se debe a que algunos componentes secundarios funcionan definidos dentro del cuerpo de otro componente funcional de React.
function App() { // A React functional component const [show, setShow] = useState(false); // etc. // A child React functional component in the body of another component... function LocationMarker() { const [position, setPosition] = useState(null); // etc. } // Another child component function LeafletControlGeocoder() { useEffect(() => {}, []); // etc. } return ( <> {/* More content... */} <MapContainer center={[45.4, -75.7]} zoom={12}> <LeafletControlGeocoder /> <LocationMarker /> </MapContainer> </> ); }Esto puede no ser problemático si los componentes secundarios no tienen estado (sin enlace). En ese caso, son más como "subplantillas".
Pero si esos componentes secundarios usan algunos ganchos, estar en el cuerpo de otro componente funcional interferirá con el funcionamiento de los ganchos: debido a que la función del componente secundario se vuelve a crear en cada nueva representación, React tiene problemas para identificar a esos elementos secundarios como el mismo componente, y termina duplicando su salida.
Simplemente asegúrese de no definir algunos componentes funcionales dentro de otro, sino siempre en el nivel superior de su alcance (normalmente en la raíz de su archivo). Como se menciona en los comentarios de la pregunta, una práctica estándar es simplemente tener 1 componente por archivo.
function App() { // A React functional component const [show, setShow] = useState(false); // etc. return ( <> {/* More content... */} <MapContainer center={[45.4, -75.7]} zoom={12}> <LeafletControlGeocoder /> <LocationMarker /> </MapContainer> </> ); } // Another React functional component at top scope level function LocationMarker() { const [position, setPosition] = useState(null); // etc. } // Another component function LeafletControlGeocoder() { useEffect(() => {}, []); // etc. }Aplicación fija: https://codesandbox.io/s/lively-monad-yve67