延迟加载React组件,直到头部脚本加载完毕

5
我有一个依赖于Google Maps js API的React组件。这个API是在App.js页面的头部使用script标签导入的。当我尝试加载包含此组件的页面时,它会失败,并声称脚本未加载。但如果我先打开不包含此组件但引用了脚本的不同页面,然后再转到包含此组件的页面,它就可以工作。
这使我想到问题可能是组件加载时脚本尚未加载。不过,我认为页面应该在获取脚本时阻塞加载。我不太确定如何解决这个问题。
App.js:
class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <Helmet>
            <script
              type="text/javascript"
              src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDSn_vNbNZzrcFxl8bV3MH1j0kuoLVsOCQ&libraries=places"
            />
          </Helmet>

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

在上述例子中,FooScreen包含这个组件,而BarScreen则不包含。如果我直接打开FooScreen,会失败;但如果我先打开BarScreen,再从中跳转到FooScreen,则可以成功。

你尝试过在你的bundle.js脚本或者无论你把自己编译的脚本叫什么之前添加谷歌地图脚本了吗? - Tholle
请提供 https://stackoverflow.com/help/mcve,以便复制问题,从而可以解决。 - Estus Flask
@estus 当然,我觉得这可能是一个快速的答案,所以我没有包含它,但现在我已经添加了代码。 - Alex
我明白了。既然你需要跟踪脚本加载,我认为Helmet不是一个好的选择。我猜你需要使用https://www.npmjs.com/package/react-async-script。 - Estus Flask
@estus 好的。我尝试过使用react-async-script,但它没有起作用。AsyncScriptLoader存在于react dom中,但行为与之前相同。 - Alex
显然,这取决于您的使用方式。有许多React和非React脚本加载库,其中一些可能更合适,但是库的选择不在SO问题的范围内。在这种情况下,Helmet能够提供更简洁的代码。 - Estus Flask
1个回答

4
通常情况下,事件监听器应该附加到脚本元素实例上,例如 基于 Promise 的脚本加载器
这种情况特指 Google 地图或其他具有异步初始化过程并接受回调的脚本,因此监听 load 事件是多余的:
  state = { mapLoaded: false };

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

  componentWillUnmount() {
    delete window.onGoogleMap;
  }

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

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

由于使用了全局变量,这意味着同时只能存在一个 App 实例,包括测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接