javascript - Delaying react component load until helmet head script loads - Stack Overflow

I have a react ponent that relies on the google maps js api. This is imported in the head of the App.js

I have a react ponent that relies on the google maps js api. This is imported in the head of the App.js page with a script tag. When I try to load the page containing this ponent, it fails, claiming that the script is not loaded. If, however, I first open a different page (which causes the script to load, but does not include this ponent), and then navigate to the page containing the ponent, it works.

This suggests to me that the issue is that the script has not yet loaded when the ponent loads. I thought, though, that the page loading should block while it gets the script. I'm not really sure how to fix this.

App.js:

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <Helmet>
            <script
              type="text/javascript"
              src=";libraries=places"
            />
          </Helmet>

          <div className="pageContent">
                <Route exact path="/foo" ponent={FooScreen} />
                <Route exact path="/bar" ponent={BarScreen} /
          </div>
        </div>
      </Router>
    );
  }
}
export default App;

In the above, FooScreen contains the ponent, and BarScreen doesn't. If I open FooScreen directly, it fails, if I open BarScreen, and then navigate to FooScreen, it works.

I have a react ponent that relies on the google maps js api. This is imported in the head of the App.js page with a script tag. When I try to load the page containing this ponent, it fails, claiming that the script is not loaded. If, however, I first open a different page (which causes the script to load, but does not include this ponent), and then navigate to the page containing the ponent, it works.

This suggests to me that the issue is that the script has not yet loaded when the ponent loads. I thought, though, that the page loading should block while it gets the script. I'm not really sure how to fix this.

App.js:

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <Helmet>
            <script
              type="text/javascript"
              src="https://maps.googleapis./maps/api/js?key=AIzaSyDSn_vNbNZzrcFxl8bV3MH1j0kuoLVsOCQ&libraries=places"
            />
          </Helmet>

          <div className="pageContent">
                <Route exact path="/foo" ponent={FooScreen} />
                <Route exact path="/bar" ponent={BarScreen} /
          </div>
        </div>
      </Router>
    );
  }
}
export default App;

In the above, FooScreen contains the ponent, and BarScreen doesn't. If I open FooScreen directly, it fails, if I open BarScreen, and then navigate to FooScreen, it works.

Share Improve this question edited Nov 4, 2018 at 18:28 Alex asked Nov 4, 2018 at 17:21 AlexAlex 2,4125 gold badges40 silver badges72 bronze badges 6
  • Have you tried putting the google maps script before your bundle.js script or whatever you call your own piled script? – Tholle Commented Nov 4, 2018 at 18:22
  • Please, provide stackoverflow./help/mcve that could replicate the problem, so it could be fixed. – Estus Flask Commented Nov 4, 2018 at 18:26
  • @estus Sure, I thought it might be a quick answer, so I didn't include it, but I've added the code now – Alex Commented Nov 4, 2018 at 18:28
  • I see. Since you need to track script loading, I don't think that Helmet is a good way to do this. I guess you need npmjs./package/react-async-script instead. – Estus Flask Commented Nov 4, 2018 at 18:33
  • @estus fair enough. I've tried to incorporate react-async-script, but it is not doing anything. The AsyncScriptLoader is present in the react dom, but the behaviour is as before – Alex Commented Nov 4, 2018 at 18:55
 |  Show 1 more ment

1 Answer 1

Reset to default 4

Usually event listeners should be attached to script element instance, e.g. promise-based script loader.

This case is specific to Google Maps or other scripts that have asynchronous initialization routine and accept a callback, so it's redundant to listen to load event:

  state = { mapLoaded: false };

  ponentDidMount() {
    window.onGoogleMap = () => this.setState({ mapLoaded: true });
  }

  ponentWillUnmount() {
    delete window.onGoogleMap;
  }

  render() {
    return <>
      <Helmet>
        <script
          type="text/javascript"
          src="https://maps.googleapis./maps/api/js?key=...&libraries=places&callback=onGoogleMap"
        />
      </Helmet>

      {!this.state.mapLoaded ? (
        'Loading...'
      ) : (
        <Router>...</Router>
      )}
    </>;
  }

Since global variable is in use, this requires no more than one instance of App to exist at the same time, including tests.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745386759a4625473.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信