Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with refs + Typescript (TiledMapLayer) #15

Closed
moranbw opened this issue Apr 7, 2022 · 5 comments
Closed

Issue with refs + Typescript (TiledMapLayer) #15

moranbw opened this issue Apr 7, 2022 · 5 comments

Comments

@moranbw
Copy link

moranbw commented Apr 7, 2022

Perhaps related to this issue, I'm having some issues with refs andTiledMapLayer. Minimal example of my code is below:

import React from 'react';
import { MapContainer, TileLayer, ZoomControl } from 'react-leaflet'
import { TiledMapLayer } from 'react-esri-leaflet';
import { TiledMapLayer as EsriTiledMapLayer } from 'esri-leaflet';
import { LatLngBoundsExpression, LatLngTuple, Map as LeafletMap, TileLayer as LeafletTileLayer } from 'leaflet';
import bbox from '@turf/bbox';
import "./Map.css";
import { useTrackedState } from '../../state';

export default function Map() {
    const state = useTrackedState();
    const [map, setMap] = React.useState<LeafletMap>();
    const esriLayerRef= React.useRef<EsriTiledMapLayer>(null);

    const bboxArray = bbox(JSON.parse(state.features));
    const corner1: LatLngTuple = [bboxArray[1], bboxArray[0]];
    const corner2: LatLngTuple = [bboxArray[3], bboxArray[2]];
    const bounds: LatLngBoundsExpression = [corner1, corner2];

    /** if panel is collapsed, reset the map and tile layer **/
    React.useEffect(() => {
        let tileLayer = esriLayerRef.current;
        if (map && tileLayer) {
            map.invalidateSize();
            tileLayer.redraw();
        }
    }, [state.panelCollapsed]);

    return (
        <MapContainer bounds={bounds} id="projectMap" zoomControl={false} whenCreated={setMap}>
                <TiledMapLayer
                    ref={navLayerRef}
                    maxNativeZoom={10} url="https://server.arcgisonline.com/ArcGIS/rest/services/the/layer"
                />
            <ZoomControl position='topright' />
        </MapContainer>
    );

}

Perhaps my tsconfig is too strict...but I'm receiving the following error:

Type 'RefObject<TiledMapLayer>' is not assignable to type 'Ref<RefObject<TiledMapLayer>> | undefined'.
  Type 'RefObject<TiledMapLayer>' is not assignable to type 'RefObject<RefObject<TiledMapLayer>>'.
    Property 'current' is missing in type 'TiledMapLayer' but required in type 'RefObject<TiledMapLayer>'.ts(2322)
[index.d.ts(81, 18): ]()'current' is declared here.
[index.d.ts(133, 9): ]()The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & TiledMapLayerOptions & RefAttributes<RefObject<TiledMapLayer>>'

Is there something going on with the way forwardRef is being used? Let me know if there's any more information I can provide.

Thanks -- and great work on this project!

@slutske22
Copy link
Owner

Thanks for opening the issue, and providing code. If you could create a codesandbox demonstrating the issue, it would be immensely helpful. I am extremely busy and have very little time to recreate issues, but if you can present me with the issue in a sandbox, I can take a look, thanks.

@moranbw
Copy link
Author

moranbw commented Apr 8, 2022

@slutske22 thanks for the prompt reply. Here's a minimal example: https://stackblitz.com/edit/vitejs-vite-vrfcaw?file=src/App.tsx

You should be able to see the TypeScript issue on line 18. In my own code, I'm just currently doing a //@ts-ignore to supress the issue.

Thanks in advance.

(note this code editor only seems to work well in Chrome, not Firefox)

@slutske22
Copy link
Owner

slutske22 commented Apr 8, 2022

I see the issue. I think I know what the problem is - I've wrapped the return value of the ref in forwardRef in React.RefObject, which I guess is wrong. I'll try to come back and fix this when I have time. For now you can fake it out by doing this

const tileLayerRef = React.useRef<React.RefObject<EsriTiledMapLayer>>(null);

// then to still get intellisense when using it:
(tileLayerRef.current as EsriTiledMapLayer).bringToBack() // or some other leaflet layer method here

Not sure when I can push a new version with the fix, I'll leave this open for now.

@moranbw
Copy link
Author

moranbw commented Apr 9, 2022

@slutske22 thanks for the workaround. No rush as it's not blocking me. If I have any time I may look into it as well, if you're open to contributions.

@slutske22
Copy link
Owner

This is fixed in version 2, which is currently in a @next version. You can try it out here: https://www.npmjs.com/package/react-esri-leaflet/v/2.0.0, npm i react-esri-leaflet@next, Will publish as official version soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants