Reputation: 3075
I have a Google Map and I am trying to update the map center with a Google Autocomplete search. I have the Searchbar in a separate JSX file from the recenter map function. How can I call this function from within my searchbar file? Below is what I tried, with this I get the error TypeError: __WEBPACK_IMPORTED_MODULE_1__map__.a.recenterMap is not a function
on the line with the comment above it
Here is my working example, and here is my code(updated based off AlainIb's response):
map.js:
export class MapContainer extends React.Component {
...
recenterMap(lat, lng) {
const map = this.map;
const google = this.props.google;
const maps = google.maps;
if (map) {
let center = new maps.LatLng(lat, lng);
map.panTo(center);
}
}
...
}
export default MapContainer;
And here is my searchbar.jsx file:
import MapContainer from './map';
/* global google */
class SearchBar extends Component {
...
handlePlaceChanged(){
const place = this.autocomplete.getPlace();
this.setState({ lat: place.geometry.location.lat() });
this.setState({ lng: place.geometry.location.lng() });
/* WHAT I TRIED */
MapContainer.recenterMap(this.state.lat, this.state.lng);
}
...
}
export default SearchBar;
Upvotes: 0
Views: 186
Reputation: 4708
You cannot do that. A class who extends React.Component
can only be called as component ( in jsx with <MapContainer />
or with routing as part of TabNavigator or StackNavigator etc )
1) You can do something like this : add a callback function inside SearchBar
component who will be called when handlePlaceChanged()
is called to set in state lat and lng, who will be passed as props to the map components
in map.js
export class MapContainer extends React.Component {
...
recenterMap() {
const {lat,lng} = this.props;
...
}
shouldComponentUpdate(nextProps) {
const diffLat= this.props.lat!== nextProps.lat;
const diffLng = this.props.done !== nextProps.lng
return diffLat|| diffLng ;
}
...
}
in SearchBar.js
export class SearchBar extends React.Component {
...
handlePlaceChanged {
...
this.props.updateParentState(lat, lng);
}
...
}
in the parent component
<SearchBar updateParentState={(lat,lng)=>{this.setState({ lat,lng }) }} />
<MapContainer lat={this.state.lat} lng={this.state.lng} />
2) if maps.js doesn't have a render function, change it as function
export function recenterMap(lat, lng,map,google) {
// pure logic
}
Upvotes: 1
Reputation: 370
If you want to share the functionality. Assuming, recenterMap does not need to share the state. You can take recenterMap function out of the component, into some other utility class. Pass the required data as arguments to this function.
class ComponentUtility {
static recenterMap(lat, lng, propGoogle) {
const map = this.map;
const maps = propGoogle.maps;
if (map) {
let center = new maps.LatLng(lat, lng);
map.panTo(center);
}
}
}
You can call this static method like:
ComponentUtility.recenterMap(lat, lng, propGoogle);
You just need to pass the right values.
Upvotes: 0