0
votes

I am following an online tutorial on implementing React with the Google Maps api. I've been trying to build my map component and I've followed the instructions exactly as they were delivered. However, when I attempt to load my page in a browser, nothing is displayed and there are some console errors that I'm having difficulty resolving.

Below is my simple HTML page

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&libraries=visualization"></script>
    </head>
    <body>
        <div id="app"></div>
        <script type="text/javascript" src="build/bundle.js" ></script>
    </body>
</html>

Here is my app.js file

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import Map from './components/Map'
import Places from './components/Places'

class App extends Component {
    render() {
        const location = {
            lat: 28.5962,
            lng: 81.3064
        }

        return (
            <div>
                This is the REACT APP!
                <div style={{width: 300, height:600, background: '#777'}}>
                    <Map center={location} />
                </div>

                <Places />
            </div>
        )
    }
}

ReactDOM.render(<App />, document.getElementById('app'))

Below is the Map.js file which I believe is causing the issue.

import React, { Component } from 'react';
import { GoogleMapLoader, GoogleMap, Marker } from 'react-google-maps';
import GoogleMapLoader from "react-google-maps-loader"

class Map extends Component {
    render(){
        const mapContainer = <div style={{height: '100%', width:'100%'}}></div>

        return (
            <GoogleMapLoader
                containerElement = { mapContainer }
                googleMapElement =  {
                    <GoogleMap
                        defaultZoom={15}
                        defaultCenter={this.props.center}
                        options={{streetViewControl: false, mapTypeControl: false}}>
                    </GoogleMap>
                } />
        )
    }
}

export default Map

This is my webpack.config.js file that transpires my JSX code to ES2015

let webpack = require("webpack");
let path = require('path');

module.exports = {
    entry: {
        app: './src/app.js'
    },
    output: {
        filename: 'build/bundle.js',
        sourceMapFilename: 'build/bundle.map'
    },
    devtool: '#source-map',
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                query:{
                    presets:['react', 'es2015']
                }
            }
        ]
    }
}

Here is a fiddle that contains the bundle.js code that is linked to my html page.

Fiddle containing bundle.js code

When I try to open in a browser, I get the following console errors

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of Map. in Map (created by App) in div (created by App) in div (created by App) in App invariant.js:49 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) >but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of Map. at invariant (invariant.js:42) at createFiberFromElement (react-dom.development.js:5753) at reconcileSingleElement (react-dom.development.js:7531) at reconcileChildFibers (react-dom.development.js:7635) at reconcileChildrenAtExpirationTime (react-dom.development.js:7756) at reconcileChildren (react-dom.development.js:7747) at finishClassComponent (react-dom.development.js:7881) at updateClassComponent (react-dom.development.js:7850) at beginWork (react-dom.development.js:8225) at performUnitOfWork (react-dom.development.js:10224) react-dom.development.js:9747 The above error occurred in the component: in Map (created by App) in div (created by App) in div (created by App) in App

react-dom.development.js:10994 Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for >composite components) but got: undefined. You likely forgot to export >your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of Map. at invariant (invariant.js:42) at createFiberFromElement (react-dom.development.js:5753) at reconcileSingleElement (react-dom.development.js:7531) at reconcileChildFibers (react-dom.development.js:7635) at reconcileChildrenAtExpirationTime (react-dom.development.js:7756) at reconcileChildren (react-dom.development.js:7747) at finishClassComponent (react-dom.development.js:7881) at updateClassComponent (react-dom.development.js:7850) at beginWork (react-dom.development.js:8225) at performUnitOfWork (react-dom.development.js:10224)

I'd thought the issue was with the GoogleMapLoader, which is why I added an import for react-google-maps-loader, but apparently that wasn't it. I also switched from using Webstorm to Sublime Text because I'd read that Webstorm has issues transpiling JSX to ES2015 code, but that too wasn't the issue. Is there something I am missing?

1

1 Answers

0
votes

The error you're facing indicates that React.createElement is receiving undefined instead of a component instance or built-in element string (such as 'div'). One of the most common possibilities would be that you forgot to install the react-google-maps package (that already happened to me a few times).

Also, before initializing the Map component you need to wrap it under a high order component called withGoogleMap.

import { GoogleMap, Marker, withGoogleMap } from "react-google-maps"

const Map = withGoogleMap((props) => 
   <GoogleMap {...props} />

export default Map;

This plugin also includes a HOC called withScriptjs in case you're not adding the Google Maps script before the closing body tag:

import { GoogleMap, Marker, withGoogleMap, withScriptjs } from "react-google-maps"

const Map = withScriptjs(withGoogleMap(props => 
    <GoogleMap {...props} />

export default Map;

More information here: https://tomchentw.github.io/react-google-maps/.