I've been having a lot of problems adding Typescript to my React code, specifically with useSate hooks.
I've spent the past few days reviewing how to fix this but I'm unsure what needs to be passed into the hooks. Should I be creating a seperate .ts
file to store what I expect in the hooks? When I scroll over the underlined errors, it keeps showing errors like:
Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.
or
Property 'features' does not exist on type '{ children?: ReactNode; }'.`
I've included my code to give a better perspective and left in the comments from the source I'm using.
import { FC } from "react";
import { useState, useEffect, useRef } from "react";
import "./mapwrapper.css";
// openlayers
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ"; //here...
import { fromLonLat } from "ol/proj";
const Home: FC<{}> = (props) => {
// set intial state
const [map, setMap] = useState();
const [featuresLayer, setFeaturesLayer] = useState();
// pull refs
const mapElement = useRef<HTMLDivElement>(null);
// create state ref that can be accessed in OpenLayers onclick callback function
// https://stackoverflow.com/a/60643670
const mapRef = useRef<{}>();
mapRef.current = map;
// initialize map on first render - logic formerly put into componentDidMount
useEffect(() => {
// create and add vector source layer
const initalFeaturesLayer = new VectorLayer({
source: new VectorSource(),
});
const seoul = [126.97794, 37.56629];
const seoulWebMercator = fromLonLat(seoul);
// create map
const initialMap = new Map({
target: mapElement.current!,
layers: [
// Google Maps Terrain
new TileLayer({
source: new XYZ({
url: "http://mt0.google.com/vt/lyrs=m&hl=en&x={x}&y={y}&z={z}",
}),
}),
initalFeaturesLayer,
],
view: new View({
projection: "EPSG:3857",
center: seoulWebMercator,
zoom: 16,
}),
controls: [],
});
// save map and vector layer references to state
setMap(initialMap);
setFeaturesLayer(initalFeaturesLayer);
}, []);
// update map if features prop changes - logic formerly put into componentDidUpdate
useEffect(() => {
if (props.features.length) {
// may be null on first render
// set features to map
featuresLayer.setSource(
new VectorSource({
features: props.features, // make sure features is an array
})
);
// fit map to feature extent (with 100px of padding)
map.getView().fit(featuresLayer.getSource().getExtent(), {
padding: [100, 100, 100, 100],
});
}
}, [props.features, featuresLayer, map]);
return (
<div>
<div ref={mapElement} className="map-container"></div>
</div>
);
};
export default Home;