Fix map staying blank until moved (#2217)

If the style arrives before the map's initial `style.load`,
`componentDidUpdate` skips `setStyle` because `state.map` is still null.
The `setState` on `style.load` is then blocked by
`shouldComponentUpdate`, because `JSON.stringify` throws on the MapLibre
`Map` in state, so the style is only applied after a later prop change,
e.g. moving the map.

Fix: `shouldComponentUpdate` compares state fields by reference instead
of stringifying them. `zoom` is excluded: it changes on every zoom frame
but is only read when a layer popup opens.

## Launch Checklist

 - [x] Briefly describe the changes in this PR.
 - [ ] ~~Link to related issues.~~
- [ ] ~~Include before/after visuals or gifs if this PR includes visual
changes.~~
 - [ ] ~~Write tests for all new functionality.~~ (removed per review)
 - [x] Add an entry to `CHANGELOG.md` under the `## main` section.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01WDkBFXcoMv8K4QSHA6P3Fg


---
_Generated by [Claude Code](https://claude.ai/code)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
zstadler
2026-10-11 17:06:18 +03:00
committed by GitHub
co-authored by Claude
parent 688a75bb69
commit 28917685f7
2 changed files with 2 additions and 1 deletions
+1
View File
@@ -17,6 +17,7 @@
- The map's data listener now fires on tile loads again, so source and vector layer field autocompletion is populated
- The `maputnik` desktop binary now opens the default browser automatically on startup (opt out with `--no-browser`)
- Keyboard shortcuts now keep working while the map has focus, instead of going dead until the map is blurred
- The map no longer stays blank on load until it is moved, when the style loads before the map is ready
- _...Add new stuff here..._
## 3.1.0
+1 -1
View File
@@ -107,7 +107,7 @@ class MapMaplibreGlInternal extends React.Component<MapMaplibreGlInternalProps,
shouldComponentUpdate(nextProps: MapMaplibreGlInternalProps, nextState: MapMaplibreGlState) {
let should = false;
try {
should = JSON.stringify(this.props) !== JSON.stringify(nextProps) || JSON.stringify(this.state) !== JSON.stringify(nextState);
should = JSON.stringify(this.props) !== JSON.stringify(nextProps) || (Object.keys(nextState) as (keyof MapMaplibreGlState)[]).some(key => key !== "zoom" && this.state[key] !== nextState[key]);
} catch(_e) {
// no biggie, carry on
}