typescript 更新全局状态数组类型脚本React中的对象

velaa5lx  于 2023-03-04  发布在  TypeScript
关注(0)|答案(1)|浏览(146)

几天来,我一直在尝试弄清楚如何更新gis项目中的全局状态数组。我使用带有ts和react的Mapbox-gl。我使用useContext钩子来跟踪“GeoJSONItems”列表,其中包括一个geoJSON对象和一些元数据。但是,当我尝试更新全局数组时,出现了几个ts问题。your text
这是我的GeoJSON上下文.tsx

import { createContext, useContext, useState } from "react";
import { FeatureCollection } from "geojson";

export type GeoJSONItem = {
  id: string,
  name: string,
  visable: boolean,
  color: string,
  geoJSON: FeatureCollection;
};

type GeoJSONContextType = {
  geoJSONList: Array<GeoJSONItem>;
  setGeoJSONList: (selected: GeoJSONItem[]) => void;
  setVisable: (value: boolean) => void;
};

const GeoJSONContext = createContext<GeoJSONContextType>({
  geoJSONList: [],
  setGeoJSONList: () => {},
  setVisable: () => {}
});

export const useGeoJSONContext = () => useContext(GeoJSONContext);

type Props = {
  children?: React.ReactNode;
};

const GeoJSONProvider: React.FC<Props> = ({ children }) => {
  const [geoJSONList, setGeoJSONList] = useState<GeoJSONItem[]>([]);
  const [visable, setVisable] = useState<boolean>(); 

  return (
    <GeoJSONContext.Provider value={{ geoJSONList, setGeoJSONList, setVisable }}>
      {children}
    </GeoJSONContext.Provider>
  );
};

export default GeoJSONProvider;

这就是useContext(适用于局部数组)处理全局状态的方式,以及我在组件中尝试的方式:
setGeoJSONs((prevGeoJSONs) => [...prevGeoJSONs, json as FeatureCollection]);
我已经设法用Array.push()解决了这个问题,但我知道这不是处理全局状态的好方法。
因此,当调用全局setGeoJSONList时,当添加或更新对象时:
setGeoJSONList((prevGeoJSONs) => [...prevGeoJSONs, json as FeatureCollection]);
ts发送此错误:类型的参数(prevGeoJSON:any)=〉any[]'无法赋值给类型为'GeoJSONItem[]'的参数,就好像它不理解prevGeoJSONs是GEOJSONItem数组一样。注意:

  • 我尝试使用ts语法和“as GeoJSONItem[]”将其转换为GeoJSONItem[]
  • 它适用于添加一个对象,但有时需要添加几个对象,然后列表将被覆盖。

希望有人有时间帮我😃

k2fxgqgv

k2fxgqgv1#

您已经将setGeoJSONList声明为(selected: GeoJSONItem[]) => void类型-换句话说,它只接受一个实际的项数组。
但是,您尝试通过向它传递一个生成项数组的函数来使用它:

setGeoJSONList((prevGeoJSONs) => [...prevGeoJSONs, json as FeatureCollection]);

useState<GeoJSONItem[]>返回的setter可以接受一个值,也可以接受一个生成值的函数;换句话说,它的类型是(selected: GeoJSONItem[] | ((prevSelected: GeoJSONItem[]) => GeoJSONItem[])) => void。只要你直接使用useState的返回值,TypeScript就能理解这一点,但是当你把它传递给一个显式类型为(selected: GeoJSONItem[]) => void的上下文属性时,它只需要数组格式。
更改生产函数的类型应该可以解决这个问题。
参见this answer

相关问题