old-examples icon indicating copy to clipboard operation
old-examples copied to clipboard

On Center Change Issues

Open mlucool opened this issue 9 years ago • 26 comments

Hi,

Whenever I zoom, I have onChange to update my zoom which should change my makers. Instead I am seeing only the map zoom and my markers not change. The console has the following the following error output (note: react 0.14). I have found it also will not ever re-render if I change the center - so for now I have put in center to be some static value.

google_map.js:691 GoogleMap center not eq: [39.73953411213935, -104.98888952907988] [39.739336111111115, -104.99163611111113]

class PictureMap extends React.Component {
...
    _onChange({center, zoom, bounds, ...other}) {
        if(!this.props.onZoomChange) return;
        this.props.onZoomChange(zoom);
        this.setState({zoom: zoom});
    }
...
    render() {.
....
        return (
            <div style={greatPlaceStyle}>
                <GoogleMap
                    center={STATIC_CENTER}
                    defaultZoom={this.props.zoom}
                    onChange={this._onChange}
                >
                    {MARKERS}
                </GoogleMap>
            </div>
        );
}
PictureMap = controllable(PictureMap, ['zoom']);

export {PictureMap};

Thanks in advance for your suggestions!

Marc

mlucool avatar Nov 26 '15 04:11 mlucool

As I see two different setState occurs, may be this is the problem To test it Just try

import { unstable_batchedUpdates } from 'react-dom'; // eslint-disable-line
 _onChange({center, zoom, bounds, ...other}) {
    unstable_batchedUpdates(() => {  
       this.props.onZoomChange(zoom);
       // change center here
       this.setState({zoom: zoom});
    });
  }

istarkov avatar Nov 26 '15 04:11 istarkov

Also If you use controllable - it has a bug with additional setState even if it does not needed. So u need to use it very accurately.

istarkov avatar Nov 26 '15 05:11 istarkov

Simplifying the example I see similar error messages. First I removed controllable. Then, I changed onChange to just call forceUpate.

_onChange({center, zoom, bounds, ...other}) {
        this.forceUpdate();
}

I have also tried it with unstable_batchedUpdates();

The error I see now is: "google_map.js:697 GoogleMap bounds not eq: [39.95968800377787, -105.27453406032988, 39.537343752155806, -104.72521765407988] [39.95021374267523, -105.26629431423612, 39.527811237785244, -104.71697790798612]"

mlucool avatar Nov 26 '15 12:11 mlucool

Have no such issue. Have fully controllable zoom an center in my projects and in a part of this examples. You can place anywhere the minimal example with this error.

istarkov avatar Nov 26 '15 17:11 istarkov

Here is working jsbin with latest GoogleMapReact version, could you show the bug there? https://jsbin.com/lepadusowo/edit?js,console,output

istarkov avatar Nov 26 '15 18:11 istarkov

Hi,

Thanks for the example! If you use the same example but change setState to _onChange = ({center, zoom}) => { this.forceUpdate(); } it reproduces the error. See: https://jsbin.com/wibufeyibe/edit?js,console,output

mlucool avatar Nov 26 '15 21:11 mlucool

It is normal behavior. As like as I want. Why you need forceUpdate here?

istarkov avatar Nov 26 '15 22:11 istarkov

Force update was my attempt to pinpoint why the following was giving me error:

this.props.onZoomChange(zoom);
this.setState({zoom: zoom});

I am new, so it is very likely my understanding of acceptable flow is wrong. On an update event, why shouldn't it be able to force a rerender right away?

mlucool avatar Dec 05 '15 20:12 mlucool

You can force rerender if you set zoom and center. It is just a wrapper over non react events generated by google api, and component behavior is the same as you set forceUpdate inside any non react like onChange event. (For example trying to combine React with some Jquery plugin)

Google API is not declarative, when I send you an onChange event - some part of google code already think that zoom or/and center has changed. It's not like in React. Even you will work with just an simple input and move onChange handler outside batched update (directly intercepting change event, or via setTimeout) you will get the same behavior.

So you can or set zoom and center as like as in example. Or use them in an uncontrollable way. (So u can refresh update etc)

istarkov avatar Dec 05 '15 21:12 istarkov

Here is simple example with other situation but it give you an idea how is to work with third party api https://jsbin.com/jadefenuza/edit?js,console,output think on input as an about some third party component.

All looks nice until you try to change input anywhere inside, http://recordit.co/3qtmlkVj2m

istarkov avatar Dec 05 '15 22:12 istarkov

Thanks for the explanation and examples!

mlucool avatar Dec 05 '15 22:12 mlucool

So the problem I am trying to solve is when I change zoom/center on the map, it update my reflux store so other components can filter on it. Similarly, when other components change these in the reflux store the map itself will update.

I can see it's similar to, but the loop I implicitly create causes issues: https://github.com/istarkov/google-map-react-examples/blob/master/web/flux/components/examples/x_events/events_map_page.jsx

Do you have any recommended approach?

mlucool avatar Dec 05 '15 22:12 mlucool

The same approach as in jsbin example The only difference that instead of setState you just call flux action, and get center and zoom from flux store. Here https://github.com/istarkov/google-map-react-examples/blob/master/web/flux/components/examples/x_main/main_map_page.jsx all is done the same way, using redux as flux. (center zoom etc is inside redux store)

istarkov avatar Dec 05 '15 23:12 istarkov

Finally got it working! At the end, I was seeing that message because although data was changing, I had a typo in my connector so my zoom/center were not getting updated in the redux store and instead cycling in the default value. Thank you for your help. This project and the examples are amazing.

mlucool avatar Dec 06 '15 23:12 mlucool

I'm trying to control map boundaries through state and get this error GoogleMap bounds not eq.

handleBoundsChange(obj) {
    let newCenter = this.lastValidCenter,
        newZoom = (obj.zoom >= this.minZoomLevel ? obj.zoom : this.minZoomLevel);
    if (this.allowedBounds &&
        this.allowedBounds.contains(new this.mapsObject.LatLng(obj.center))) {
      newCenter = this.lastValidCenter = obj.center;
    }
    this.setState({
      center: newCenter,
      zoom: newZoom
    });
  }
<GoogleMap
        center={this.state.center}
        zoom={this.state.zoom}
        options={mapconfig}
        onChange={::this.handleBoundsChange}>
</GoogleMap>

fruitkiwi avatar Feb 03 '16 13:02 fruitkiwi

If u close console, does your code works? Is your problem in warning message only?

istarkov avatar Feb 03 '16 17:02 istarkov

Yes it brings the center back if it exceedes the bounds, but zoom level stays the same, not changing back to minZoomLevel

fruitkiwi avatar Feb 04 '16 04:02 fruitkiwi

@fruitkiwi Found this issue will work at today.

istarkov avatar Feb 12 '16 11:02 istarkov

I'm getting this GoogleMap bounds not eq warning whenever I specify an onChange. This occurs even if my onChange callback is completely empty! So just adding the following line

onChange={(settings) => { console.log('do nothing'); } }

causes the warnings to occur.

I'm using mobx but don't think that's related. These warnings are not just cosmetic - I've got a bug where the map just zooms back and forth forever by itself, but while trying to debug it I noticed that even this simple case gives warnings. I'm on version 0.14.4.

thunderkid avatar Jun 23 '16 01:06 thunderkid

I can confirm that the GoogleMap bounds not eq warning is happening with:

test() {
  console.log('foo');
}

<GoogleMap onChange={this.test}>

Mobx isn't the reason, I'm using Redux with SSR, for example. If i remove onChange the warning doesn't appear anymore. I'd be happy to offer more details if you need

SerbanC avatar Jun 28 '16 13:06 SerbanC

I'm seeing the same problem. Only happening when I change zoom AND center. Changing center by itself doesn't throw the "bounds not eq" error. Confused, bc the bounds should have changed if zoom and center change.

worldlyjohn avatar Jun 28 '16 13:06 worldlyjohn

Hi @istarkov : I am facing some rendering issue. Need your help, can you please tell me how can i refresh the map. I need to refresh map because in my case i am resizing wrapper so it doesn't render to the new height.

nishankkumar1994 avatar Jun 28 '16 14:06 nishankkumar1994

@SerbanC: I've been getting the same warning, but I just got it to go away by updating to the newest version of the package and adding the following attribute to the component:

<GoogleMap resetBoundsOnResize {...props } />

as per this PR. Hope that helps.

lustrousgorilla avatar Oct 12 '16 04:10 lustrousgorilla

Hi Guys,

N00bie here and I am having issue triggering the re-centring of the map using the onChildClick option of the GoogleMap element:

<GoogleMap
     bootstrapURLKeys={{key: 'XXXxxyyyYYY'}}
     center={this.props.center}
     zoom={this.props.zoom}
     hoverDistance={K_SIZE / 2}
     onChange={this._onChange}
     onChildClick={this._onChildClick}
     onChildMouseEnter={this._onChildMouseEnter}
     onChildMouseLeave={this._onChildMouseLeave}
 >
              {this._siteGen()}
</GoogleMap>

This is my _onChildClick function:

  _onChildClick = (key, childProps) => {
    for(var i =0;i!=this.state.cntry.length;i++)
      if(this.state.cntry[i]._id == key ){
        this.setState({title: this.state.cntry[i].name});
        this.props.onCenterChange([childProps.lat, childProps.lng]);
    }
  }

This does nothing even though I have confirmed that the childProps values are correct. I experimented with using states, i.e.:

<GoogleMap
     bootstrapURLKeys={{key: 'XXXxxyyyYYY'}}
     center={this.state.center}
     zoom={this.state.zoom}
     hoverDistance={K_SIZE / 2}
     onChange={this._onChange}
     onChildClick={this._onChildClick}
     onChildMouseEnter={this._onChildMouseEnter}
     onChildMouseLeave={this._onChildMouseLeave}
 >
              {this._siteGen()}
</GoogleMap>
  _onChildClick = (key, childProps) => {
    for(var i =0;i!=this.state.cntry.length;i++)
      if(this.state.cntry[i]._id == key ){
        this.setState({title: this.state.cntry[i].name,
                             center:[childProps.lat, childProps.lng],
                             zoom: this.state.cntry[i}.Zoom);
    }
  }

Zoom works but the map remains on the original center value and this can be done only once. Im not sure if this was answered before, but reading through the comments it seems this is not issuing that is being reported even though the title seems to suggest this problem.

Any ideas as how to get this working ?

mactac27 avatar Mar 24 '17 01:03 mactac27

Please provide jsbin example. As the code you provided above contains syntax errors image

istarkov avatar Mar 24 '17 06:03 istarkov

I faced the same issue and the easiest solution is to remove the element and then add it back. {this.state.showMap && <GoogleMapReact> .... </GoogleMapReact> }

You can set showMap state flag to false and then using setTimeout(()=>{ me.setState({showMap:true},200)}

Works like charm. Maybe not the best UX but not that bad either

urigg123 avatar Feb 18 '18 23:02 urigg123