What ended up working is calculating the new latitude, longitude, and zoom for my new extent I was zooming to using WebMercatorViewport, and then set that as the new viewport state. I used the FlyToInterpolator method that react-map-gl offers to fly to that location.

const {longitude, latitude, zoom } = new WebMercatorViewport(this.state.viewport)
.fitBounds([[extent[0], extent[1]], [extent[2], extent[3]]], {padding: {top: 82, bottom: 30, left: leftPadding, right: 30}});
const viewport = {
  ...this.state.viewport,
  longitude,
  latitude,
  zoom,
  transitionDuration: 2000,
  transitionInterpolator: new FlyToInterpolator()
}
this.setState({viewport});
Answer from dugtoni on Stack Overflow
🌐
Snyk
snyk.io › advisor › react-map-gl › functions › react-map-gl.fitbounds
How to use the react-map-gl.fitBounds function in react-map-gl | Snyk
August 19, 2022 - uber / react-map-gl / test / utils / fit-bounds.spec.js View on Github · test('fitBounds', (t) => { for (const [{viewport, bounds, options}, expected] of FITBOUNDS_TEST_CASES) { const result = fitBounds(viewport, bounds, options); t.ok(Number.isFinite(result.longitude), 'get valid longitude'); t.ok(Number.isFinite(result.latitude), 'get valid latitude'); t.ok(Number.isFinite(result.zoom), 'get valid zoom'); t.deepEqual( toLowPrecision(result), toLowPrecision(expected), 'valid viewport returned' ); } t.end(); });
🌐
DEV Community
dev.to › ivanbtrujillo › fit-viewport-to-markers-using-react-map-gl-3ig1
Fit viewport to markers using react-map-gl - DEV Community
December 20, 2020 - React.useEffect(() => { if (width ... as WebMercatorViewport), width, height }).fitBounds(MARKERS_BOUNDS as Bounds, { padding: 100 }); return NEXT_VIEWPORT; }); } }, [width, height]); ......
🌐
Mapbox
docs.mapbox.com › all docs
Fit a map to a bounding box | Mapbox GL JS | Mapbox
The fitBounds() method accepts a geographic bounding box representing the southwest and northeast corners of the area you would like to fit the map's viewport to. The coordinates must be passed in as a LngLatBoundsLike (A LngLatBounds object, ...
🌐
Stack Overflow
stackoverflow.com › questions › 52911719 › locate-to-specific-bound-by-using-fitbounds-of-react-mapbox-gl
reactjs - Locate to specific bound by using fitBounds of react-mapbox-gl - Stack Overflow
October 21, 2018 - <CustomMapbox showAll={this.state.showAll} center={this.state.center} fitBounds={this.state.bound} zoom={[8]} containerStyle={{ height: "100%" }} onClick={this.onClickMap} > <Marker locations={this.state.places} data={this.state.product} onClick={this.onClickPosition} /> { (this.state.selectedPoint ) && (this.state.showPopup) && <Popup key={`${this.state.selectedPoint[0]}_${this.state.selectedPoint[1]}`} coordinates={this.state.selectedPoint}> <StyledPopup> <div>{this.state.selectedUPCDate}</div> </StyledPopup> </Popup> } </CustomMapbox>
Top answer
1 of 2
3

The input am passing to fitBounds should be in the form of Array<Array<number>>

getMinOrMax(markersObj, minOrMax, latOrLng) {
 if(minOrMax == "max"){
  return _.maxBy(markersObj, function (value) {
      return value[latOrLng]
  })[latOrLng];
 }else{
  return _.minBy(markersObj, function (value) {
      return value[latOrLng]
  })[latOrLng];
 }
}

getBounds(markersObj) {
  var maxLat = this.getMinOrMax(markersObj, "max", "lat");
  var minLat = this.getMinOrMax(markersObj, "min", "lat");
  var maxLng = this.getMinOrMax(markersObj, "max", "lng");
  var minLng = this.getMinOrMax(markersObj, "min", "lng");

  var southWest = [minLng, minLat];
  var northEast = [maxLng, maxLat];
  return [southWest, northEast];
}

So am using the above methods to find figure out SouthWest and NorthEast points from the given array of marker position objects.

Marker sample objects should to be like below:

var markerPoints = [{lng:12.49637,lat:41.90278},{lng:12.319398,lat:45.441906},{lng:13.055054,lat:47.809532},{lng:16.373724,lat:48.208244}]

<Map
  style="mapbox://styles/mapbox/streets-v9"
  containerStyle={{
   height: "100%",
   width: "100%"
  }}
  fitBounds={this.getBounds(markerPoints)}>
  <markers /> 
</Map>  

Note: Am using lodash liblary for utility functions like min and max in the example.

Thanks,
Josan

2 of 2
3

You are passing the wrong bounds format to the fitBounds() function.

Fit bounds expects as an argument: fitBounds : Array<Array<number>>

See the docs: https://github.com/alex3165/react-mapbox-gl/blob/master/docs/API.md

In mapbox this is called an "LngLatBoundsLike Object", see here: https://www.mapbox.com/mapbox-gl-js/api/#lnglatlike

So your function call must be something like this:

fitBounds([[12.49637,41.90278],[12.319398,45.441906]]);

Where the first argument is the southwest corner and the second argument is the northeast corner of your desired bounding box

🌐
GitHub
github.com › visgl › react-map-gl › issues › 1099
Using LngLatBounds · Issue #1099 · visgl/react-map-gl
May 10, 2020 - I am trying to use LngLatBounds. Importing it from the mapbox library directly generates many errors (I am using NextJS), such as "self is not defined". But I feel like it's related t...
Published   May 10, 2020
Author   jordymeow
🌐
Stack Overflow
stackoverflow.com › questions › 74850416 › fit-bounds-with-padding-deck-gl-mapbox
reactjs - Fit bounds with padding deck.gl mapbox - Stack Overflow
I am not using deck.gl, but here is what did with react-map-gl. <Map initialViewState={{ bounds: getBoundingBox(fitLocations), fitBoundsOptions: { padding: 60 }, }} > ... </Map> For generating the bounding box we can use the same code provided by on Ar26.
Find elsewhere
🌐
UNPKG
unpkg.com › browse › react-mapbox-gl@5.1.1 › lib › map.d.ts
react-mapbox-gl
import * as MapboxGl from 'mapbox-gl'; import * as React from 'react'; import { Events, Listeners } from './map-events'; export interface PaddingOptions { top: number; bottom: number; left: number; right: number; } export interface FitBoundsOptions { linear?: boolean; easing?: (time: number) => number; padding?: number | PaddingOptions; offset?: MapboxGl.Point | [number, number]; maxZoom?: number; duration?: number; } export declare type FitBounds = [[number, number], [number, number]]; export interface AnimationOptions { duration: number; animate: boolean; easing(time: number): number; offset
🌐
React Map GL
visgl.github.io › what's new
What's new | react-map-gl
fitBounds: fitBounds has been moved to another repository and has been rewritten to provide a more logical interface. For more information, see the Upgrade Guide. ... Perspective Mode - Now supports bearing and pitch properties, per mapbox-gl api documentation.
🌐
GitHub
github.com › visgl › react-map-gl › blob › master › docs › upgrade-guide.md
react-map-gl/docs/upgrade-guide.md at master · visgl/react-map-gl
April 13, 2021 - Overlays must be Children of the Map - Overlays must now be rendered as children of the main react-map-gl component to automatically sync with the map viewport. The fitBounds utility has been moved to the math.gl library.
Author   visgl
Top answer
1 of 1
1

Got it working like this:

import React, { useState } from "react";
import ReactMapGL, { Marker, WebMercatorViewport } from "react-map-gl";
import * as parkData from "./data.json";
const mapIcon: any = require('../images/mapIcon.png');

const applyToArray = (func, array) => func.apply(Math, array)

const getBoundsForPoints = (points) => {
  console.log('Points:', points)
  // Calculate corner values of bounds
  const pointsLong = points.map(point => point.geometry.coordinates[0])
  const pointsLat = points.map(point => point.geometry.coordinates[1])
  const cornersLongLat = [
    [applyToArray(Math.min, pointsLong), applyToArray(Math.min, pointsLat)],
    [applyToArray(Math.max, pointsLong), applyToArray(Math.max, pointsLat)]
  ]
  // Use WebMercatorViewport to get center longitude/latitude and zoom
  const viewport = new WebMercatorViewport({ width: 600, height: 600 })
    // @ts-ignore
    .fitBounds(cornersLongLat, { padding: {top:150, bottom:200, left:100, right:150} }) 
  const { longitude, latitude, zoom } = viewport
  return { longitude, latitude, zoom }
}

const myMap = () => {

  const bounds = getBoundsForPoints(parkData.features);

  const [viewport, setViewport] = useState({
    width: "100%",
    height: "600px",
    ...bounds
  });
  const [selectedPark, setSelectedPark] = useState(null);
  
  return (
    <div>
      <ReactMapGL
        {...viewport}
        mapboxApiAccessToken="pk.eyJ1IjoiYmVubmtpbmd5IiwiYSI6ImNrY2ozMnJ5dzBrZ28ycnA1b2Vqb2I0bXgifQ.ZOaVtzsDQOrAovh9Orh13Q"
        mapStyle="mapbox://styles/mapbox/streets-v11"
        onViewportChange={viewport => {
          setViewport(viewport);
        }}

      >
        {parkData.features.map(park => (
          <Marker
            key={park.properties.PARK_ID}
            latitude={park.geometry.coordinates[1]}
            longitude={park.geometry.coordinates[0]}
          >
            <button
              className="marker-btn"
              onClick={e => {
                e.preventDefault();
                setSelectedPark(park);
              }}
            >
              <img src={mapIcon} alt="Map Pointer Icon" />
            </button>
          </Marker>
        ))}
      </ReactMapGL>
      {selectedPark ? (
        <div>
          <h2>{selectedPark.properties.NAME}</h2>
          <p>{selectedPark.properties.DESCRIPTIO}</p>
          <button onClick={e => {
                e.preventDefault();
                setSelectedPark(null);
              }}>X</button>
        </div>
      ) : null}
    </div>
  );
}

export default myMap;
🌐
React Map GL
visgl.github.io › upgrade guide
Upgrade Guide | react-map-gl
Overlays must be Children of the Map - Overlays must now be rendered as children of the main react-map-gl component to automatically sync with the map viewport. The fitBounds utility has been moved to the math.gl library.
🌐
GitHub
github.com › visgl › react-map-gl › issues › 242
Getting map bounds · Issue #242 · visgl/react-map-gl
May 16, 2017 - visgl / react-map-gl Public · Notifications · You must be signed in to change notification settings · Fork 1.4k · Star 8.4k · New issueCopy link · New issueCopy link · Closed · Closed · Getting map bounds#242 · Copy link · G2Jose · opened · on May 16, 2017 ·
Published   May 16, 2017
Author   G2Jose
🌐
Lightrun
lightrun.com › answers › google-map-react-google-map-react-initializing-map-with-fitbounds-when-map-size-is-dynamic
Initializing map with fitBounds when map size is dynamic
... fitBounds() pans and zooms the map viewport...Read more > ... You create a Map by specifying a container and other options. Then MapLibre GL JS initializes the map on the page and returns...Read more >
🌐
GitHub
github.com › visgl › react-map-gl › issues › 987
fitBounds not a prop of MapGL · Issue #987 · visgl/react-map-gl
January 11, 2020 - In the documentation is says you can set the bounds of your map by using the fitBounds prop. There is no prop on the MapGL. fitBounds does nothing. There is also no bounds prop How can I set the bounds of the map? Below is the interface ...
Author   porteron
🌐
GitHub
github.com › alex3165 › react-mapbox-gl › issues › 469
Set fitBounds only initially · Issue #469 · alex3165/react-mapbox-gl
December 6, 2017 - I want to set initial fitBounds when the map loads for the first time. If I do so, the map goes back to these bounds whenever data changes (it's supposed to be a live map with moving Features). Tha...
Author   cloudlena
🌐
Arden
arden.nl › getting-started-with-mapbox-gl-js
Getting started with Mapbox GL JS | Arden.nl
For the result I cleaned up the code a bit by fitting the markers code and the fitbounds code into separate functions. Feel free to fork this on Codepen! When creating a couple of test maps I also realised, an interactive map with different data layers can get complicated quickly. That’s why I continued my adventure with Mapbox GL JS in React.
🌐
GitHub
github.com › alex3165 › react-mapbox-gl › issues › 78
Add Fitbounds support · Issue #78 · alex3165/react-mapbox-gl
December 13, 2016 - Behavior would be similar to maxBounds but without the constraints in panning. Usage could also be similar by feeding the property and array of all marker coordinates, however it might simply make more sense to have it work with a boolean and ...
Author   timlogemann