Skip to content

fix: only call setData on a GeoJSON source when data changes - #2622

Open
tordans wants to merge 1 commit into
visgl:masterfrom
tordans:fix/geojson-source-setdata
Open

tordans wants to merge 1 commit into
visgl:masterfrom
tordans:fix/geojson-source-setdata

Conversation

@tordans

@tordans tordans commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Disclaimer: Found and fixed with Clause Opus 5.5 High. Description also written by Claude and reviewed by me.

The problem

updateSource() calls setData(props.data) on a GeoJSON <Source> when any prop changes, not only data. So changing tolerance, maxzoom, buffer or promoteId sends props.data again.

Some apps don't pass their features through the data prop. They render the source once with a placeholder, such as data={EMPTY}, and then push the real features themselves with map.getSource(id).setData(...) or updateData(...). That saves React from deep-comparing large GeoJSON on every render. From react-map-gl's side, data never changes, so it should leave the source alone.

<Source id="osm" type="geojson" data={EMPTY} tolerance={tolerance} />
// elsewhere: map.getSource('osm').setData(features)

If such an app changes any other prop, tolerance in this example, react-map-gl calls setData(EMPTY). That replaces the app's features with the empty placeholder, and the map shows nothing until the app pushes its data again. The new tolerance doesn't take effect either: MapLibre and Mapbox read that option only when the source is added, so the source keeps the old value.

The change

For a geojson source, setData is now called only when data changed. Any other changed prop gets the same Unable to update <Source> prop: ... warning that the other source types already log. Applied to source.ts in react-maplibre and react-mapbox; I left the mapbox-legacy copy in modules/main alone.

Relation to #2618: that PR applies cluster, clusterMaxZoom and clusterRadius changes with setClusterOptions and skips setData when only those changed (maplibre only). This PR covers the remaining props and both packages. The two touch the same lines, so whichever lands second needs a small rebase: in the loop over the changed keys, the cluster keys go to setClusterOptions instead of the warning.

New test in both packages: data set with source.setData() is kept after tolerance changes, and the warning is logged. It fails without the change. The existing Source/Layer test still covers a changed data prop.

Validation: TypeScript build, yarn lint, and all 86 node/headless tests pass.


Note

Medium Risk
Changes core Source update behavior for all GeoJSON sources; low blast radius but could affect apps that relied on incidental setData on non-data prop changes.

Overview
Fixes GeoJSON <Source> updates so imperative setData / updateData is not wiped when unrelated props change.

updateSource in react-mapbox and react-maplibre used to call setData(props.data) on every prop change for type="geojson". Apps that mount with placeholder data and push features via the map API would lose those features when e.g. tolerance changed, because React re-sent the empty placeholder.

The geojson branch now iterates changed props: setData runs only when data changed; other keys log Unable to update <Source> prop: …, matching behavior for non-geojson sources. Tests cover keeping imperative data after a tolerance change and asserting the warning.

Reviewed by Cursor Bugbot for commit 226fc15. Bugbot is set up for automated code reviews on this repo. Configure here.

A change to any other prop of a GeoJSON <Source> (e.g. tolerance, maxzoom)
re-sent props.data, which overwrote data set with setData/updateData, and the
option itself was not applied. Now setData is only called for a changed data
prop; other changed props are reported with the same warning as other source
types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] This PR appears safe to merge.

Summary

This PR prevents unrelated GeoJSON prop changes from overwriting data set directly on the map.

  • GeoJSON sources keep pushed data when another prop changes.

Reviews (1) · Last reviewed commit: "fix: only call setData on a GeoJSON sour..." · Reviewed by Greptile

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant