Closed
Description
I discovered that the Map component's declared event listeners are being re-attached on every state update, which results in the listener firing n
times per click, where n
is the number of times the parent component's state has been updated since its initial render.
Here's a minimal example, which can be copied and pasted into https://code.esm.sh and reproduced by clicking on the map a few times and then opening the console and checking the log statements. The first click yields one log statement, while the second click results in two (i.e. three total), the third in three (six total), and so forth.
<!DOCTYPE html>
<html>
<head>
<title>@planet/maps with esm.sh</title>
<script type="importmap">
{
"imports": {
"htm": "https://esm.sh/htm",
"react": "https://esm.sh/[email protected]",
"react-dom/": "https://esm.sh/[email protected]/",
"@planet/maps/": "https://esm.sh/@planet/maps/"
}
}
</script>
<link href="https://esm.sh/[email protected]/ol.css" rel="stylesheet">
<style>
html,
body {
margin: 0;
}
#root {
position: absolute;
top: 0;
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module">
import Map from '@planet/maps/Map';
import View from '@planet/maps/View';
import ScaleLine from '@planet/maps/control/ScaleLine';
import TileLayer from '@planet/maps/layer/WebGLTile';
import OSM from '@planet/maps/source/OSM';
import htm from 'htm';
import React from 'react';
import {createRoot} from 'react-dom/client';
const html = htm.bind(React.createElement);
function App() {
const [count, setCount] = React.useState(0);
return html`
<div>Count is ${count}</div>
<${Map} onClick=${(e)=> console.log("CLICK") || setCount(count+1)} style=${{width: '100%', height: '100%'}}>
<${View} options=${{center: [0, 0], zoom: 1}} />
<${TileLayer}>
<${OSM} />
</${TileLayer}>
<${ScaleLine} />
</${Map}>
`;
}
const root = createRoot(document.getElementById('root'));
root.render(html`<${App} />`);
</script>
</body>
</html>
Metadata
Metadata
Assignees
Labels
No labels