Tengo un componente funcional de React que tiene un mapa de folleto de reacción que se representa en el lado del servidor. El mapa se muestra perfectamente, pero cuando agrego una función de controlador de eventos de clic para pasar al componente principal, aparece el error: No se puede desestructurar la propiedad 'MapContainer' de 'reactLeaflet' porque es nulo. Este es el código en el componente secundario:
const MyMap = (props, ref) => { const [ reactLeaflet, setReactLeaflet ] = useState(null); const [ position, setPosition ] = useState(null); useEffect(() => { const loadData = async () => { // react-leaflet errors if imported server-side (with "ReferenceError: window is not defined") // not sure if this load can happen in parallel with leaflet.js or not import('react-leaflet') .then(leaflet => setReactLeaflet(leaflet)) .catch(error => noticeError(null, levels.error, error, "react-leaflet failed to load")); }; loadData(); }, []); const { MapContainer, Marker, Popup, TileLayer, useMapEvents, } = reactLeaflet; const HandleClickMap = (e) =>{ const currMap = useMapEvents({ click() { currMap.locate(); }, locationfound(e) { setPosition(e.latlng); currMap.flyTo(e.latlng, currMap.getZoom()); }, }); return position === null ? null : ( <Marker position={position}></Marker> ); }; useImperativeHandle(ref, () => ({ HandleClickMap, })); if (!reactLeaflet) { return <LeafletCss />; } return <> <LeafletCss /> <MapContainer center={{ lat: 0, lng: 0 }} zoom={13} ref={ref} scrollWheelZoom={false} className={style.mapContainer} > <TileLayer attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' /> <HandleClickMap /> </MapContainer> </>; }; export default forwardRef(MyMap);
Este problema ocurrió cuando agregué el gancho useImperativeHandle . Cualquier idea de por qué es apreciada.
Compruebe si el objeto reactLeaflet
se ha importado antes de intentar acceder a sus componentes
const MyMap = (props) => { const { MapContainer, Marker, Popup, TileLayer, useMapEvents, } = props.reactLeaflet; const [ position, setPosition ] = useState(null); const HandleClickMap = (e) =>{ const currMap = useMapEvents({ click() { currMap.locate(); }, locationfound(e) { setPosition(e.latlng); currMap.flyTo(e.latlng, currMap.getZoom()); }, }); return position === null ? null : ( <Marker position={position}></Marker> ); }; useImperativeHandle(props.ref, () => ({ HandleClickMap, })); return <> <LeafletCss /> <MapContainer center={{ lat: 0, lng: 0 }} zoom={13} ref={ref} scrollWheelZoom={false} className={style.mapContainer} > <TileLayer attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' /> <HandleClickMap /> </MapContainer> </>; } const MapLoader = (props, ref) => { const [ reactLeaflet, setReactLeaflet ] = useState(null); useEffect(() => { const loadData = async () => { import('react-leaflet') .then(leaflet => setReactLeaflet(leaflet)) .catch(error => noticeError(null, levels.error, error, "react-leaflet failed to load")); }; loadData(); }, []); return (reactLeaflet ? <MyMap reactLeaflet={reactLeaflet} ref={ref} /> : <LeafletCss /> ); }; export default forwardRef(MapLoader);