user13286
user13286

Reputation: 3075

Call a function from a class in another file

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

Answers (2)

AlainIb
AlainIb

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

Rajesh Dwivedi
Rajesh Dwivedi

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

Related Questions