diff --git a/web/src/beta/lib/core/engines/Cesium/core/Imagery.test.ts b/web/src/beta/lib/core/engines/Cesium/core/Imagery.test.ts
index 60f67528b1..6e6efeed3a 100644
--- a/web/src/beta/lib/core/engines/Cesium/core/Imagery.test.ts
+++ b/web/src/beta/lib/core/engines/Cesium/core/Imagery.test.ts
@@ -1,103 +1,117 @@
-import { renderHook } from "@testing-library/react";
+import { renderHook, act } from "@testing-library/react";
import { expect, test, vi } from "vitest";
import { type Tile, useImageryProviders } from "./Imagery";
-test("useImageryProviders", () => {
+test("useImageryProviders", async () => {
const provider = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge: url }));
const provider2 = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge2: url }));
const presets = { default: provider, foobar: provider2 };
- const { result, rerender } = renderHook(
- ({ tiles, cesiumIonAccessToken }: { tiles: Tile[]; cesiumIonAccessToken?: string }) =>
- useImageryProviders({
- tiles,
- presets,
- cesiumIonAccessToken,
- }),
- { initialProps: { tiles: [{ id: "1", tile_type: "default" }] } },
- );
+ let result: any;
+ let rerender: any;
+
+ await act(async () => {
+ const renderResult = renderHook(
+ ({ tiles, cesiumIonAccessToken }: { tiles: Tile[]; cesiumIonAccessToken?: string }) =>
+ useImageryProviders({
+ tiles,
+ presets,
+ cesiumIonAccessToken,
+ }),
+ { initialProps: { tiles: [{ id: "1", tile_type: "default" }] } },
+ );
+ result = renderResult.result;
+ rerender = renderResult.rerender;
+ });
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
- expect(result.current.updated).toBe(true);
expect(provider).toBeCalledTimes(1);
const prevImageryProvider = result.current.providers["1"][2];
// re-render with same tiles
- rerender({ tiles: [{ id: "1", tile_type: "default" }] });
+ await act(async () => {
+ rerender({ tiles: [{ id: "1", tile_type: "default" }] });
+ });
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
- expect(result.current.updated).toBe(false);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider); // 1's provider should be reused
expect(provider).toBeCalledTimes(1);
// update a tile URL
- rerender({ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }] });
+ await act(async () => {
+ rerender({ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }] });
+ });
expect(result.current.providers).toEqual({ "1": ["default", "a", { hoge: "a" }] });
expect(result.current.providers["1"][2]).not.toBe(prevImageryProvider);
- expect(result.current.updated).toBe(true);
expect(provider).toBeCalledTimes(2);
expect(provider).toBeCalledWith({ url: "a" });
const prevImageryProvider2 = result.current.providers["1"][2];
// add a tile with URL
- rerender({
- tiles: [
- { id: "2", tile_type: "default" },
- { id: "1", tile_type: "default", tile_url: "a" },
- ],
+ await act(async () => {
+ rerender({
+ tiles: [
+ { id: "2", tile_type: "default" },
+ { id: "1", tile_type: "default", tile_url: "a" },
+ ],
+ });
});
expect(result.current.providers).toEqual({
"2": ["default", undefined, { hoge: undefined }],
"1": ["default", "a", { hoge: "a" }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider2); // 1's provider should be reused
- expect(provider).toBeCalledTimes(3);
+ expect(provider).toBeCalledTimes(2);
// sort tiles
- rerender({
- tiles: [
- { id: "1", tile_type: "default", tile_url: "a" },
- { id: "2", tile_type: "default" },
- ],
+ await act(async () => {
+ rerender({
+ tiles: [
+ { id: "1", tile_type: "default", tile_url: "a" },
+ { id: "2", tile_type: "default" },
+ ],
+ });
});
expect(result.current.providers).toEqual({
"1": ["default", "a", { hoge: "a" }],
"2": ["default", undefined, { hoge: undefined }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider2); // 1's provider should be reused
- expect(provider).toBeCalledTimes(3);
+ expect(provider).toBeCalledTimes(2);
// delete a tile
- rerender({
- tiles: [{ id: "1", tile_type: "default", tile_url: "a" }],
- cesiumIonAccessToken: "a",
+ await act(async () => {
+ rerender({
+ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }],
+ cesiumIonAccessToken: "a",
+ });
});
expect(result.current.providers).toEqual({
"1": ["default", "a", { hoge: "a" }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).not.toBe(prevImageryProvider2);
- expect(provider).toBeCalledTimes(4);
+ expect(provider).toBeCalledTimes(3);
// update a tile type
- rerender({
- tiles: [{ id: "1", tile_type: "foobar", tile_url: "u" }],
- cesiumIonAccessToken: "a",
+ await act(async () => {
+ rerender({
+ tiles: [{ id: "1", tile_type: "foobar", tile_url: "u" }],
+ cesiumIonAccessToken: "a",
+ });
});
expect(result.current.providers).toEqual({
"1": ["foobar", "u", { hoge2: "u" }],
});
- expect(result.current.updated).toBe(true);
- expect(provider).toBeCalledTimes(4);
+ expect(provider).toBeCalledTimes(3);
expect(provider2).toBeCalledTimes(1);
- rerender({ tiles: [] });
+ await act(async () => {
+ rerender({ tiles: [] });
+ });
expect(result.current.providers).toEqual({});
});
diff --git a/web/src/beta/lib/core/engines/Cesium/core/Imagery.tsx b/web/src/beta/lib/core/engines/Cesium/core/Imagery.tsx
index d504f98fe8..62dcc2baee 100644
--- a/web/src/beta/lib/core/engines/Cesium/core/Imagery.tsx
+++ b/web/src/beta/lib/core/engines/Cesium/core/Imagery.tsx
@@ -1,6 +1,5 @@
import { ImageryProvider } from "cesium";
-import { isEqual } from "lodash-es";
-import { useCallback, useMemo, useRef, useLayoutEffect } from "react";
+import { useMemo, useState, useEffect, useCallback, useRef } from "react";
import { ImageryLayer } from "resium";
import { tiles as tilePresets } from "./presets";
@@ -28,45 +27,44 @@ export type Props = {
};
export default function ImageryLayers({ tiles, cesiumIonAccessToken }: Props) {
- const { providers, updated } = useImageryProviders({
+ const { providers } = useImageryProviders({
tiles,
cesiumIonAccessToken,
presets: tilePresets,
});
- // force rerendering all layers when any provider is updated
- // since Resium does not sort layers according to ImageryLayer component order
- const counter = useRef(0);
- useLayoutEffect(() => {
- if (updated) counter.current++;
- }, [providers, updated]);
+ const memoTiles = useMemo(
+ () =>
+ tiles
+ ?.map(({ id, ...tile }) => ({ ...tile, id, provider: providers[id]?.[2] }))
+ .filter(({ provider }) => !!provider) ?? [],
+ [tiles, providers],
+ );
return (
<>
- {tiles
- ?.map(({ id, ...tile }) => ({ ...tile, id, provider: providers[id]?.[2] }))
- .map(({ id, tile_opacity: opacity, tile_minLevel: min, tile_maxLevel: max, provider }, i) =>
- provider ? (
-
- ) : null,
- )}
+ {memoTiles.map(
+ ({ id, tile_opacity: opacity, tile_minLevel: min, tile_maxLevel: max, provider }, i) => (
+
+ ),
+ )}
>
);
}
type Providers = {
- [id: string]: [
- string | undefined,
- string | undefined,
- Promise | ImageryProvider,
- ];
+ [id: string]: [string | undefined, string | undefined, ImageryProvider];
+};
+
+type ResolvedProviders = {
+ [id: string]: ImageryProvider;
};
export function useImageryProviders({
@@ -82,92 +80,41 @@ export function useImageryProviders({
cesiumIonAccessToken?: string;
}) => Promise | ImageryProvider | null;
};
-}): { providers: Providers; updated: boolean } {
- const newTile = useCallback(
- (t: Tile, ciat?: string) =>
- presets[t.tile_type || "default"]({ url: t.tile_url, cesiumIonAccessToken: ciat }),
- [presets],
+}): {
+ providers: Providers;
+} {
+ const resolvedPresetProviders = useRef({});
+ const [providers, setProviders] = useState({});
+
+ const providerKey = useCallback(
+ (t: Omit) => `${t.tile_type || "default"}_${t.tile_url}_${cesiumIonAccessToken}`,
+ [cesiumIonAccessToken],
);
- const prevCesiumIonAccessToken = useRef(cesiumIonAccessToken);
- const tileKeys = tiles.map(t => t.id).join(",");
- const prevTileKeys = useRef(tileKeys);
- const prevProviders = useRef({});
-
- // Manage TileProviders so that TileProvider does not need to be recreated each time tiles are updated.
- const { providers, updated } = useMemo(() => {
- const isCesiumAccessTokenUpdated = prevCesiumIonAccessToken.current !== cesiumIonAccessToken;
- const prevProvidersKeys = Object.keys(prevProviders.current);
- const added = tiles.map(t => t.id).filter(t => t && !prevProvidersKeys.includes(t));
-
- const rawProviders = [
- ...Object.entries(prevProviders.current),
- ...added.map(a => [a, undefined] as const),
- ].map(([k, v]) => ({
- key: k,
- added: added.includes(k),
- prevType: v?.[0],
- prevUrl: v?.[1],
- prevProvider: v?.[2],
- tile: tiles.find(t => t.id === k),
- }));
-
- const providers = Object.fromEntries(
- rawProviders
- .map(
- ({
- key,
- added,
- prevType,
- prevUrl,
- prevProvider,
- tile,
- }):
- | [
- string,
- [
- string | undefined,
- string | undefined,
- Promise | ImageryProvider | null | undefined,
- ],
- ]
- | null =>
- !tile
- ? null
- : [
- key,
- added ||
- prevType !== tile.tile_type ||
- prevUrl !== tile.tile_url ||
- (isCesiumAccessTokenUpdated && (!tile.tile_type || tile.tile_type === "default"))
- ? [tile.tile_type, tile.tile_url, newTile(tile, cesiumIonAccessToken)]
- : [prevType, prevUrl, prevProvider],
- ],
- )
- .filter(
- (
- e,
- ): e is [
- string,
- [string | undefined, string | undefined, Promise | ImageryProvider],
- ] => !!e?.[1][2],
+ useEffect(() => {
+ Promise.all(
+ tiles.map(async t => {
+ if (!Object.keys(resolvedPresetProviders.current).includes(providerKey(t))) {
+ const newProvider = await presets[t.tile_type || "default"]({
+ url: t.tile_url,
+ cesiumIonAccessToken,
+ });
+ if (newProvider) {
+ resolvedPresetProviders.current[providerKey(t)] = newProvider;
+ }
+ }
+ }),
+ ).then(() => {
+ setProviders(
+ Object.fromEntries(
+ tiles.map(({ id, ...t }) => [
+ id,
+ [t.tile_type, t.tile_url, resolvedPresetProviders.current[providerKey(t)]],
+ ]),
),
- );
-
- const updated =
- !!added.length ||
- !!isCesiumAccessTokenUpdated ||
- !isEqual(prevTileKeys.current, tileKeys) ||
- rawProviders.some(
- p => p.tile && (p.prevType !== p.tile.tile_type || p.prevUrl !== p.tile.tile_url),
);
+ });
+ }, [tiles, cesiumIonAccessToken, presets, resolvedPresetProviders, providerKey]);
- prevTileKeys.current = tileKeys;
- prevCesiumIonAccessToken.current = cesiumIonAccessToken;
-
- return { providers, updated };
- }, [cesiumIonAccessToken, tiles, tileKeys, newTile]);
-
- prevProviders.current = providers;
- return { providers, updated };
+ return { providers };
}
diff --git a/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.test.ts b/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.test.ts
index 60f67528b1..6e6efeed3a 100644
--- a/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.test.ts
+++ b/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.test.ts
@@ -1,103 +1,117 @@
-import { renderHook } from "@testing-library/react";
+import { renderHook, act } from "@testing-library/react";
import { expect, test, vi } from "vitest";
import { type Tile, useImageryProviders } from "./Imagery";
-test("useImageryProviders", () => {
+test("useImageryProviders", async () => {
const provider = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge: url }));
const provider2 = vi.fn(({ url }: { url?: string } = {}): any => ({ hoge2: url }));
const presets = { default: provider, foobar: provider2 };
- const { result, rerender } = renderHook(
- ({ tiles, cesiumIonAccessToken }: { tiles: Tile[]; cesiumIonAccessToken?: string }) =>
- useImageryProviders({
- tiles,
- presets,
- cesiumIonAccessToken,
- }),
- { initialProps: { tiles: [{ id: "1", tile_type: "default" }] } },
- );
+ let result: any;
+ let rerender: any;
+
+ await act(async () => {
+ const renderResult = renderHook(
+ ({ tiles, cesiumIonAccessToken }: { tiles: Tile[]; cesiumIonAccessToken?: string }) =>
+ useImageryProviders({
+ tiles,
+ presets,
+ cesiumIonAccessToken,
+ }),
+ { initialProps: { tiles: [{ id: "1", tile_type: "default" }] } },
+ );
+ result = renderResult.result;
+ rerender = renderResult.rerender;
+ });
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
- expect(result.current.updated).toBe(true);
expect(provider).toBeCalledTimes(1);
const prevImageryProvider = result.current.providers["1"][2];
// re-render with same tiles
- rerender({ tiles: [{ id: "1", tile_type: "default" }] });
+ await act(async () => {
+ rerender({ tiles: [{ id: "1", tile_type: "default" }] });
+ });
expect(result.current.providers).toEqual({ "1": ["default", undefined, { hoge: undefined }] });
- expect(result.current.updated).toBe(false);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider); // 1's provider should be reused
expect(provider).toBeCalledTimes(1);
// update a tile URL
- rerender({ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }] });
+ await act(async () => {
+ rerender({ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }] });
+ });
expect(result.current.providers).toEqual({ "1": ["default", "a", { hoge: "a" }] });
expect(result.current.providers["1"][2]).not.toBe(prevImageryProvider);
- expect(result.current.updated).toBe(true);
expect(provider).toBeCalledTimes(2);
expect(provider).toBeCalledWith({ url: "a" });
const prevImageryProvider2 = result.current.providers["1"][2];
// add a tile with URL
- rerender({
- tiles: [
- { id: "2", tile_type: "default" },
- { id: "1", tile_type: "default", tile_url: "a" },
- ],
+ await act(async () => {
+ rerender({
+ tiles: [
+ { id: "2", tile_type: "default" },
+ { id: "1", tile_type: "default", tile_url: "a" },
+ ],
+ });
});
expect(result.current.providers).toEqual({
"2": ["default", undefined, { hoge: undefined }],
"1": ["default", "a", { hoge: "a" }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider2); // 1's provider should be reused
- expect(provider).toBeCalledTimes(3);
+ expect(provider).toBeCalledTimes(2);
// sort tiles
- rerender({
- tiles: [
- { id: "1", tile_type: "default", tile_url: "a" },
- { id: "2", tile_type: "default" },
- ],
+ await act(async () => {
+ rerender({
+ tiles: [
+ { id: "1", tile_type: "default", tile_url: "a" },
+ { id: "2", tile_type: "default" },
+ ],
+ });
});
expect(result.current.providers).toEqual({
"1": ["default", "a", { hoge: "a" }],
"2": ["default", undefined, { hoge: undefined }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).toBe(prevImageryProvider2); // 1's provider should be reused
- expect(provider).toBeCalledTimes(3);
+ expect(provider).toBeCalledTimes(2);
// delete a tile
- rerender({
- tiles: [{ id: "1", tile_type: "default", tile_url: "a" }],
- cesiumIonAccessToken: "a",
+ await act(async () => {
+ rerender({
+ tiles: [{ id: "1", tile_type: "default", tile_url: "a" }],
+ cesiumIonAccessToken: "a",
+ });
});
expect(result.current.providers).toEqual({
"1": ["default", "a", { hoge: "a" }],
});
- expect(result.current.updated).toBe(true);
expect(result.current.providers["1"][2]).not.toBe(prevImageryProvider2);
- expect(provider).toBeCalledTimes(4);
+ expect(provider).toBeCalledTimes(3);
// update a tile type
- rerender({
- tiles: [{ id: "1", tile_type: "foobar", tile_url: "u" }],
- cesiumIonAccessToken: "a",
+ await act(async () => {
+ rerender({
+ tiles: [{ id: "1", tile_type: "foobar", tile_url: "u" }],
+ cesiumIonAccessToken: "a",
+ });
});
expect(result.current.providers).toEqual({
"1": ["foobar", "u", { hoge2: "u" }],
});
- expect(result.current.updated).toBe(true);
- expect(provider).toBeCalledTimes(4);
+ expect(provider).toBeCalledTimes(3);
expect(provider2).toBeCalledTimes(1);
- rerender({ tiles: [] });
+ await act(async () => {
+ rerender({ tiles: [] });
+ });
expect(result.current.providers).toEqual({});
});
diff --git a/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.tsx b/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.tsx
index 2f5797e99b..62dcc2baee 100644
--- a/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.tsx
+++ b/web/src/classic/components/molecules/Visualizer/Engine/Cesium/core/Imagery.tsx
@@ -1,6 +1,5 @@
import { ImageryProvider } from "cesium";
-import { isEqual } from "lodash-es";
-import { useCallback, useMemo, useRef, useLayoutEffect } from "react";
+import { useMemo, useState, useEffect, useCallback, useRef } from "react";
import { ImageryLayer } from "resium";
import { tiles as tilePresets } from "./presets";
@@ -28,44 +27,44 @@ export type Props = {
};
export default function ImageryLayers({ tiles, cesiumIonAccessToken }: Props) {
- const { providers, updated } = useImageryProviders({
+ const { providers } = useImageryProviders({
tiles,
cesiumIonAccessToken,
presets: tilePresets,
});
- // force rerendering all layers when any provider is updated
- // since Resium does not sort layers according to ImageryLayer component order
- const counter = useRef(0);
- useLayoutEffect(() => {
- if (updated) counter.current++;
- }, [providers, updated]);
+ const memoTiles = useMemo(
+ () =>
+ tiles
+ ?.map(({ id, ...tile }) => ({ ...tile, id, provider: providers[id]?.[2] }))
+ .filter(({ provider }) => !!provider) ?? [],
+ [tiles, providers],
+ );
return (
<>
- {tiles
- ?.map(({ id, ...tile }) => ({ ...tile, id, provider: providers[id]?.[2] }))
- .map(({ id, tile_opacity: opacity, tile_minLevel: min, tile_maxLevel: max, provider }, i) =>
- provider ? (
-
- ) : null,
- )}
+ {memoTiles.map(
+ ({ id, tile_opacity: opacity, tile_minLevel: min, tile_maxLevel: max, provider }, i) => (
+
+ ),
+ )}
>
);
}
type Providers = {
- [id: string]: [
- string | undefined,
- string | undefined,
- Promise | ImageryProvider,
- ];
+ [id: string]: [string | undefined, string | undefined, ImageryProvider];
+};
+
+type ResolvedProviders = {
+ [id: string]: ImageryProvider;
};
export function useImageryProviders({
@@ -81,92 +80,41 @@ export function useImageryProviders({
cesiumIonAccessToken?: string;
}) => Promise | ImageryProvider | null;
};
-}): { providers: Providers; updated: boolean } {
- const newTile = useCallback(
- (t: Tile, ciat?: string) =>
- presets[t.tile_type || "default"]({ url: t.tile_url, cesiumIonAccessToken: ciat }),
- [presets],
+}): {
+ providers: Providers;
+} {
+ const resolvedPresetProviders = useRef({});
+ const [providers, setProviders] = useState({});
+
+ const providerKey = useCallback(
+ (t: Omit) => `${t.tile_type || "default"}_${t.tile_url}_${cesiumIonAccessToken}`,
+ [cesiumIonAccessToken],
);
- const prevCesiumIonAccessToken = useRef(cesiumIonAccessToken);
- const tileKeys = tiles.map(t => t.id).join(",");
- const prevTileKeys = useRef(tileKeys);
- const prevProviders = useRef({});
-
- // Manage TileProviders so that TileProvider does not need to be recreated each time tiles are updated.
- const { providers, updated } = useMemo(() => {
- const isCesiumAccessTokenUpdated = prevCesiumIonAccessToken.current !== cesiumIonAccessToken;
- const prevProvidersKeys = Object.keys(prevProviders.current);
- const added = tiles.map(t => t.id).filter(t => t && !prevProvidersKeys.includes(t));
-
- const rawProviders = [
- ...Object.entries(prevProviders.current),
- ...added.map(a => [a, undefined] as const),
- ].map(([k, v]) => ({
- key: k,
- added: added.includes(k),
- prevType: v?.[0],
- prevUrl: v?.[1],
- prevProvider: v?.[2],
- tile: tiles.find(t => t.id === k),
- }));
-
- const providers = Object.fromEntries(
- rawProviders
- .map(
- ({
- key,
- added,
- prevType,
- prevUrl,
- prevProvider,
- tile,
- }):
- | [
- string,
- [
- string | undefined,
- string | undefined,
- Promise | ImageryProvider | null | undefined,
- ],
- ]
- | null =>
- !tile
- ? null
- : [
- key,
- added ||
- prevType !== tile.tile_type ||
- prevUrl !== tile.tile_url ||
- (isCesiumAccessTokenUpdated && (!tile.tile_type || tile.tile_type === "default"))
- ? [tile.tile_type, tile.tile_url, newTile(tile, cesiumIonAccessToken)]
- : [prevType, prevUrl, prevProvider],
- ],
- )
- .filter(
- (
- e,
- ): e is [
- string,
- [string | undefined, string | undefined, Promise | ImageryProvider],
- ] => !!e?.[1][2],
+ useEffect(() => {
+ Promise.all(
+ tiles.map(async t => {
+ if (!Object.keys(resolvedPresetProviders.current).includes(providerKey(t))) {
+ const newProvider = await presets[t.tile_type || "default"]({
+ url: t.tile_url,
+ cesiumIonAccessToken,
+ });
+ if (newProvider) {
+ resolvedPresetProviders.current[providerKey(t)] = newProvider;
+ }
+ }
+ }),
+ ).then(() => {
+ setProviders(
+ Object.fromEntries(
+ tiles.map(({ id, ...t }) => [
+ id,
+ [t.tile_type, t.tile_url, resolvedPresetProviders.current[providerKey(t)]],
+ ]),
),
- );
-
- const updated =
- !!added.length ||
- !!isCesiumAccessTokenUpdated ||
- !isEqual(prevTileKeys.current, tileKeys) ||
- rawProviders.some(
- p => p.tile && (p.prevType !== p.tile.tile_type || p.prevUrl !== p.tile.tile_url),
);
+ });
+ }, [tiles, cesiumIonAccessToken, presets, resolvedPresetProviders, providerKey]);
- prevTileKeys.current = tileKeys;
- prevCesiumIonAccessToken.current = cesiumIonAccessToken;
-
- return { providers, updated };
- }, [cesiumIonAccessToken, tiles, tileKeys, newTile]);
-
- prevProviders.current = providers;
- return { providers, updated };
+ return { providers };
}