我不知道如何将 Typescript 添加到我的 React useState 挂钩中,我做错了什么?
I can't figure out how to add Typescript to my React useState hooks, what am I doing wrong?
我在将 Typescript 添加到我的 React 代码时遇到了很多问题,特别是在使用 useSate 挂钩时。
过去几天我一直在研究如何解决这个问题,但我不确定需要将什么传递到挂钩中。我应该创建一个单独的 .ts
文件来存储我在挂钩中期望的内容吗?当我滚动带下划线的错误时,它一直显示如下错误:
Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'.
Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.
或
Property 'features' does not exist on type '{ children?: ReactNode; }'.`
我已经包含了我的代码以提供更好的视角,并在评论中留下了我正在使用的来源。
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
//
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;
在 TypeScript 中,您需要声明所有类型,包括对象类型中的所有属性。
从您提供的错误信息来看,这两个错误是因为您没有声明正确的类型。
Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.
这个错误是因为你没有为useState
声明类型,所以默认为undefined
。您可以通过执行以下操作轻松修复它:
// You should substitute `any` type to a more appropriate type.
const [map, setMap] = useState<Map<any, any>>();
Property 'features' does not exist on type '{ children?: ReactNode; }'.`
这个错误是因为你没有在组件props的类型中声明需要的属性
type HomeProps = {
// You should substitute `any` type to a more appropriate type.
features: any;
};
const Home: FC<HomeProps> = (props) => {
...
}
可能还有更多类似的错误是您没有正确声明类型。您需要做的就是声明它们。
对于地图问题,您应该明确提供类型
const [map, setMap] = useState<Map>();
对于feature和featureLayer的问题,你应该提供道具类型
type HomeProps = { features: any[] };
const Home: FC<HomeProps> = (props) => {
const [map, setMap] = useState<Map>();
const [featuresLayer, setFeaturesLayer] = useState<
VectorLayer<VectorSource<Geometry>>
>();
...
useEffect(() => {
if (props.features?.length && featuresLayer) {
...
}
}, [props.features, featuresLayer, map]);
}
我在将 Typescript 添加到我的 React 代码时遇到了很多问题,特别是在使用 useSate 挂钩时。
过去几天我一直在研究如何解决这个问题,但我不确定需要将什么传递到挂钩中。我应该创建一个单独的 .ts
文件来存储我在挂钩中期望的内容吗?当我滚动带下划线的错误时,它一直显示如下错误:
Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.
或
Property 'features' does not exist on type '{ children?: ReactNode; }'.`
我已经包含了我的代码以提供更好的视角,并在评论中留下了我正在使用的来源。
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
//
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;
在 TypeScript 中,您需要声明所有类型,包括对象类型中的所有属性。
从您提供的错误信息来看,这两个错误是因为您没有声明正确的类型。
Argument of type 'Map' is not assignable to parameter of type 'SetStateAction'. Type 'Map' provides no match for the signature '(prevState: undefined): undefined'.
这个错误是因为你没有为useState
声明类型,所以默认为undefined
。您可以通过执行以下操作轻松修复它:
// You should substitute `any` type to a more appropriate type.
const [map, setMap] = useState<Map<any, any>>();
Property 'features' does not exist on type '{ children?: ReactNode; }'.`
这个错误是因为你没有在组件props的类型中声明需要的属性
type HomeProps = {
// You should substitute `any` type to a more appropriate type.
features: any;
};
const Home: FC<HomeProps> = (props) => {
...
}
可能还有更多类似的错误是您没有正确声明类型。您需要做的就是声明它们。
对于地图问题,您应该明确提供类型
const [map, setMap] = useState<Map>();
对于feature和featureLayer的问题,你应该提供道具类型
type HomeProps = { features: any[] };
const Home: FC<HomeProps> = (props) => {
const [map, setMap] = useState<Map>();
const [featuresLayer, setFeaturesLayer] = useState<
VectorLayer<VectorSource<Geometry>>
>();
...
useEffect(() => {
if (props.features?.length && featuresLayer) {
...
}
}, [props.features, featuresLayer, map]);
}