Avoid uncessessary rerendering (see https://medium.com/swlh/making-stupid-react-smart-in-re-rendering-5f04b5bab327 ).
This commit is contained in:
parent
ab5c8ff6bb
commit
a7f78e0fa9
|
@ -1,4 +1,4 @@
|
||||||
import react, { useState } from 'react';
|
import react, { useCallback, useState } from 'react';
|
||||||
import Handlers from './Handlers';
|
import Handlers from './Handlers';
|
||||||
import Tile from './Tile';
|
import Tile from './Tile';
|
||||||
import TiledLayer from './TiledLayer';
|
import TiledLayer from './TiledLayer';
|
||||||
|
@ -16,10 +16,13 @@ export const Map: react.FC<MapProperties> = (props: MapProperties) => {
|
||||||
shift: { x: 0, y: 0 },
|
shift: { x: 0, y: 0 },
|
||||||
});
|
});
|
||||||
|
|
||||||
const simpleTileFactory: TileFactory = (keyObject) => (
|
const simpleTileFactory: TileFactory = useCallback(
|
||||||
<Tile
|
(keyObject) => (
|
||||||
href={`https://tile.openstreetmap.org/${keyObject.zoomLevel}/${keyObject.x}/${keyObject.y}.png`}
|
<Tile
|
||||||
/>
|
href={`https://tile.openstreetmap.org/${keyObject.zoomLevel}/${keyObject.x}/${keyObject.y}.png`}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const transformMap = (
|
const transformMap = (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import react, { useRef } from 'react';
|
import react, { memo, useRef } from 'react';
|
||||||
import { range, isEqual } from 'lodash';
|
import { range, isEqual } from 'lodash';
|
||||||
|
|
||||||
import { Rectangle, TileFactory, TileKeyObject } from './types';
|
import { Rectangle, TileFactory, TileKeyObject } from './types';
|
||||||
|
@ -23,45 +23,46 @@ export interface TiledLayerProperties {
|
||||||
*
|
*
|
||||||
* This component has no need to know the number nor the size of its tiles: tiles can be added when needed and
|
* This component has no need to know the number nor the size of its tiles: tiles can be added when needed and
|
||||||
* its unit is the tile size (the parent component needs to transform its enclosing SVG group to adapt its units)
|
* its unit is the tile size (the parent component needs to transform its enclosing SVG group to adapt its units)
|
||||||
*
|
*
|
||||||
* TODO: test tiles'X and Y boundaries.
|
* TODO: test tiles'X and Y boundaries.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export const TiledLayer: react.FC<TiledLayerProperties> = (
|
export const TiledLayer: react.FC<TiledLayerProperties> = memo(
|
||||||
props: TiledLayerProperties
|
(props: TiledLayerProperties) => {
|
||||||
) => {
|
console.log(`Rendering TiledLayer: ${JSON.stringify(props)}`);
|
||||||
console.log(`Rendering TiledLayer: ${JSON.stringify(props)}`);
|
const tiles = useRef<any>({});
|
||||||
const tiles = useRef<any>({});
|
const previousKeyObject = useRef<TileKeyObject>(props.keyObject);
|
||||||
const previousKeyObject = useRef<TileKeyObject>(props.keyObject);
|
if (!isEqual(props.keyObject, previousKeyObject.current)) {
|
||||||
if (!isEqual(props.keyObject, previousKeyObject.current)) {
|
previousKeyObject.current = props.keyObject;
|
||||||
previousKeyObject.current = props.keyObject;
|
tiles.current = {};
|
||||||
tiles.current = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
range(props.viewPort.topLeft.y, props.viewPort.bottomRight.y + 1).map(
|
|
||||||
(row) => {
|
|
||||||
range(props.viewPort.topLeft.x, props.viewPort.bottomRight.x + 1).map(
|
|
||||||
(col) => {
|
|
||||||
const keyObject = {
|
|
||||||
provider: props.keyObject.provider,
|
|
||||||
zoomLevel: props.keyObject.zoomLevel,
|
|
||||||
x: props.keyObject.x + col,
|
|
||||||
y: props.keyObject.y + row,
|
|
||||||
};
|
|
||||||
const key = tileUri(keyObject);
|
|
||||||
if (!Object.hasOwn(tiles.current, key)) {
|
|
||||||
tiles.current[key] = (
|
|
||||||
<g key={key} transform={`translate(${col}, ${row})`}>
|
|
||||||
{props.tileFactory(keyObject)}
|
|
||||||
</g>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return <>{Object.values(tiles.current)}</>;
|
range(props.viewPort.topLeft.y, props.viewPort.bottomRight.y + 1).map(
|
||||||
};
|
(row) => {
|
||||||
|
range(props.viewPort.topLeft.x, props.viewPort.bottomRight.x + 1).map(
|
||||||
|
(col) => {
|
||||||
|
const keyObject = {
|
||||||
|
provider: props.keyObject.provider,
|
||||||
|
zoomLevel: props.keyObject.zoomLevel,
|
||||||
|
x: props.keyObject.x + col,
|
||||||
|
y: props.keyObject.y + row,
|
||||||
|
};
|
||||||
|
const key = tileUri(keyObject);
|
||||||
|
if (!Object.hasOwn(tiles.current, key)) {
|
||||||
|
tiles.current[key] = (
|
||||||
|
<g key={key} transform={`translate(${col}, ${row})`}>
|
||||||
|
{props.tileFactory(keyObject)}
|
||||||
|
</g>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return <>{Object.values(tiles.current)}</>;
|
||||||
|
},
|
||||||
|
isEqual
|
||||||
|
);
|
||||||
|
|
||||||
export default TiledLayer;
|
export default TiledLayer;
|
||||||
|
|
Loading…
Reference in New Issue