Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On Center Change Issues #8

Open
mlucool opened this issue Nov 26, 2015 · 26 comments
Open

On Center Change Issues #8

mlucool opened this issue Nov 26, 2015 · 26 comments

Comments

@mlucool
Copy link

mlucool commented Nov 26, 2015

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

@istarkov
Copy link
Collaborator

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
Copy link
Collaborator

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.

@mlucool
Copy link
Author

mlucool commented Nov 26, 2015

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]"

@istarkov
Copy link
Collaborator

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
Copy link
Collaborator

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

@mlucool
Copy link
Author

mlucool commented Nov 26, 2015

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

@istarkov
Copy link
Collaborator

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

@mlucool
Copy link
Author

mlucool commented Dec 5, 2015

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?

@istarkov
Copy link
Collaborator

istarkov commented Dec 5, 2015

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
Copy link
Collaborator

istarkov commented Dec 5, 2015

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

@mlucool
Copy link
Author

mlucool commented Dec 5, 2015

Thanks for the explanation and examples!

@mlucool
Copy link
Author

mlucool commented Dec 5, 2015

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?

@istarkov
Copy link
Collaborator

istarkov commented Dec 5, 2015

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)

@mlucool
Copy link
Author

mlucool commented Dec 6, 2015

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 mlucool closed this as completed Dec 10, 2015
@fruitkiwi
Copy link

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>

@istarkov
Copy link
Collaborator

istarkov commented Feb 3, 2016

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

@fruitkiwi
Copy link

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

@istarkov
Copy link
Collaborator

@fruitkiwi Found this issue will work at today.

@istarkov istarkov reopened this Feb 12, 2016
@thunderkid
Copy link

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.

@SerbanC
Copy link

SerbanC commented Jun 28, 2016

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

@worldlyjohn
Copy link

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.

@nishankkumar1994
Copy link

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.

@lustrousgorilla
Copy link

lustrousgorilla commented Oct 12, 2016

@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.

@mactac27
Copy link

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 ?

@istarkov
Copy link
Collaborator

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

@urigg123
Copy link

urigg123 commented Feb 18, 2018

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

....

}

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

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

No branches or pull requests

10 participants