Open blainegarrett opened 6 years ago
which is the status of this ?
What can I do to help? This is affecting me as I need to put a <Link/>
inside the InfoWindow
or at least a onClick
function to redirect users once they click on it. Also I ended up here by investigating the error message You should not use <Link> outside a <Router>
given when I put a <Link/>
inside the InfoWindow
. I haven't figured a workaround yet.
Unfortunately, I never had time to make a PR and I've since moved on from the project and I don't know that my solution is the best. Somewhere I started investigating the use of "Portals" but had to move on to other things.
That said, I ended up with something like:
// MyMapComponnent
showPopup() {
// This is the clickhandler bound in the renderDomCallback for the infoWindow
// TODO: Investigate Portal?
let slug = this.state.selectedPlace.slug;
this.props.router.push({
pathname: `/galleries/${slug}`,
state: {
modal: true,
returnTo: '/gallery/guide?'
}
});
}
renderDomCallback(domElement) {
// This is passed down to the InfoWindow
// TODO: Investigate Portal
let a = domElement.querySelector("a#galleryPopupLink"); // id of Material-UI <Button /> inside of VenueRenderer component
if (a) {
a.addEventListener('click', this.showPopup.bind(this));
}
return domElement;
}
render () {
...
return (
<Map ...>
...
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
...
renderDomCallback={this.renderDomCallback.bind(this)}>
<MapInfoWindowContent>
<VenueRenderer resource={ this.state.selectedPlace } />
</MapInfoWindowContent>
</InfoWindow>
</Map>
);
Wrap MyMapComponent in withRouter() HOC from react-router
. I'm leveraging several Material-UI bits, but mine looks like:
export default compose(withWidth(), withStyles(styles, { withTheme: true }))(withRouter(APIEnabledMap));
where ApiEnabledMap
is
let APIMap = GoogleApiWrapper({
apiKey: GOOGLE_MAPS_API_KEY,
libraries: ['places','visualization'],
})(MyMapComponent);```
The change to google-maps-react Inside my forked google-maps-react/components/InfoWindow component class:
renderChildren() {
const {children} = this.props;
var domWrapper = document.createElement('DIV');
domWrapper.innerHTML = ReactDOMServer.renderToString(children);
if (this.props.renderDomCallback) {
domWrapper = this.props.renderDomCallback(domWrapper);
}
return domWrapper;
}
Here is that same method in current master sans callback: https://github.com/fullstackreact/google-maps-react/blob/master/src/components/InfoWindow.js#L96
Basically, once the dom is rendered inside the infowindow, I'm calling the provided callback I passed in via props. From here, I just find the target element and bind click handlers. Not ideal, but works.
As far as Material-UI goes, the
export default function MapInfoWindowContent({children}) {
return (<ThemeProvider>{children}</ThemeProvider>);
}
That said, there might be a way to address this problem using "Portals" but I never dug that far into them. Either/or, I think you still would need a callback to wrap the dom.
More information on portals: https://reactjs.org/docs/portals.html
Any chance this problem gets resolved? I really need to use Link in InfoWindow. Thanks!
Hey @blainegarrett, any chance to see the code above on a repo? I'm struggling to make the InfoWindow popup/modal available with a Route. It seems you have succeed? Many thanks in advance
Is there still an activity here? I really need this to work but I can't figure it out...
Use case: The contents of my InfoWindow are Material-UI components that contain Buttons that utilize React Router and ultimately show a dialog. Currently, the InfoWindow component renders the children as a string and set this to the content of the infoWindow.setContent(renderedString). As such all event bindings are lost.
After experimenting, it seems infoWindow.setContent() can also take a dom element. If InfoWindow.renderChildren() could conditionally pass the rendered dom to a callback to further process it, we'd have an edge to rebind clickhandlers, etc.
I have gotten this to work on an older fork of google-maps-react. I have only tested it with React Router 3 and component. I assume react's sythentic events need to rebound for more general use, but I didn't need this for my use case. I'll try to branch latest master and make a PR adding this functionality.