Skip to content

Commit

Permalink
feat(async/ScriptjsLoader): replacement of async/ScriptjsGoogleMap
Browse files Browse the repository at this point in the history
* Mark async/ScriptjsGoogleMap as deprecated
* Closes #145
* Ref #92

BREAKING CHANGE: migrate from async/ScriptjsGoogleMap to async/ScriptjsLoader and changed its behavior from implicit inheritance to simple delegation

To migrate the code follow the example below (extracted from examples/gh-pages migration):

Before:

```js
<ScriptjsLoader
  hostname={"maps.googleapis.com"}
  pathname={"/maps/api/js"}
  query={{v: `3.exp`, libraries: "geometry,drawing,places"}}
  //
  // <GoogleMap> props
  defaultZoom={3}
  defaultCenter={{lat: -25.363882, lng: 131.044922}}
  onClick={::this._handle_map_click}
/>
```

After:

```js
<ScriptjsLoader
  hostname={"maps.googleapis.com"}
  pathname={"/maps/api/js"}
  query={{v: `3.exp`, libraries: "geometry,drawing,places"}}
  //
  googleMapElement={
    <GoogleMap
      defaultZoom={3}
      defaultCenter={{lat: -25.363882, lng: 131.044922}}
      onClick={::this._handle_map_click}
    />
  }
/>
```
  • Loading branch information
tomchentw committed Nov 21, 2015
1 parent 0a301c4 commit ccfadd4
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 42 deletions.
65 changes: 23 additions & 42 deletions src/async/ScriptjsGoogleMap.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
default as canUseDOM,
} from "can-use-dom";

import {
default as warning,
} from "warning";
Expand All @@ -17,49 +12,35 @@ import {
} from "../index";

import {
default as makeUrl,
urlObjDefinition,
getUrlObjChangedKeys,
} from "../utils/makeUrl";
default as ScriptjsLoader,
} from "./ScriptjsLoader";

export default class ScriptjsGoogleMap extends Component {
static propTypes = {
...urlObjDefinition,
// PropTypes for ScriptjsGoogleMap
loadingElement: PropTypes.node,
}

state = {
isLoaded: false,
}

componentWillMount () {
if (!canUseDOM) {
return;
}
const scriptjs = require("scriptjs");
const {protocol, hostname, port, pathname, query, ...restProps} = this.props;
const urlObj = {protocol, hostname, port, pathname, query};
const url = makeUrl(urlObj);
scriptjs(url, () => this.setState({ isLoaded: true }));
}

componentWillReceiveProps (nextProps) {
if ("production" !== process.env.NODE_ENV) {
const changedKeys = getUrlObjChangedKeys(this.props, nextProps);

warning(0 === changedKeys.length, `ScriptjsGoogleMap doesn't support mutating url related props after initial render. Changed props: %s`, `[${ changedKeys.join(", ") }]`);
}
warning(false,
`"async/ScriptjsGoogleMap" is deprecated now and will be removed in next major release (5.0.0). Use "async/ScriptjsLoader" instead.
See https://github.com/tomchentw/react-google-maps/pull/150 for more details.`
);
}

render () {
if (this.state.isLoaded) {
const {protocol, hostname, port, pathname, query, ...restProps} = this.props;
return (
<GoogleMap {...restProps} />
);
} else {
return this.props.loadingElement;
}
const {protocol, hostname, port, pathname, query, loadingElement, children, ...restProps} = this.props;

return (
<ScriptjsLoader
protocol={protocol}
hostname={hostname}
port={port}
pathname={pathname}
query={query}
loadingElement={loadingElement}
googleMapElement={
<GoogleMap {...restProps}>
{children}
</GoogleMap>
}
/>
)
}
}
69 changes: 69 additions & 0 deletions src/async/ScriptjsLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {
default as React,
Component,
PropTypes,
} from "react";

import {
default as canUseDOM,
} from "can-use-dom";

import {
default as warning,
} from "warning";

import {
GoogleMap,
} from "../index";

import {
default as makeUrl,
urlObjDefinition,
getUrlObjChangedKeys,
} from "../utils/makeUrl";

export default class ScriptjsLoader extends Component {
static propTypes = {
...urlObjDefinition,
// PropTypes for ScriptjsLoader
loadingElement: PropTypes.node,
googleMapElement: PropTypes.element.isRequired,
}

state = {
isLoaded: false,
}

componentWillMount () {
if (!canUseDOM) {
return;
}
/*
* External commonjs require dependency -- begin
*/
const scriptjs = require("scriptjs");
/*
* External commonjs require dependency -- end
*/
const {protocol, hostname, port, pathname, query} = this.props;
const urlObj = {protocol, hostname, port, pathname, query};
const url = makeUrl(urlObj);
scriptjs(url, () => this.setState({ isLoaded: true }));

This comment has been minimized.

Copy link
@maciejmyslinski

maciejmyslinski Dec 2, 2015

What if somebody add two SciptjsLoaders as sibling? Will both load google maps api? Will it not break the app?

This comment has been minimized.

Copy link
@tomchentw

tomchentw Dec 3, 2015

Author Owner

AFAIK, scriptjs will try to load the same url just once. It has internal caching for this. But if there's different url……hmmm. I think there's nothing I can do for this.

}

componentWillReceiveProps (nextProps) {
if ("production" !== process.env.NODE_ENV) {
const changedKeys = getUrlObjChangedKeys(this.props, nextProps);

warning(0 === changedKeys.length, `ScriptjsLoader doesn't support mutating url related props after initial render. Changed props: %s`, `[${ changedKeys.join(", ") }]`);
}
}

render () {
if (this.state.isLoaded) {
return this.props.googleMapElement;
} else {
return this.props.loadingElement;
}
}
}

0 comments on commit ccfadd4

Please sign in to comment.