【问题标题】:Script load in react脚本加载反应
【发布时间】:2017-03-17 00:25:01
【问题描述】:

我想从 CDN 加载脚本,然后在 React 中执行该脚本公开的函数:

componentWillMount() {
    console.log('componentWillMount is called');
    const script = document.createElement('script');
    script.src = 'https://foo.azurewebsites.net/foo.js';
    document.body.appendChild(script);
}


componentDidMount() {
    console.log('componentDidMount is called');
    window.foo.render({
        formId: '77fd8848-791a-4f13-9c82-d24f9290edd7',
    }, '#container');
}


render() {
    console.log('render is called');
    return (
        <div id="container"></div>
    );
}

脚本有时需要一些时间来加载(通常是第一次),当 componentDidMount() 被称为“foo”时不可用,我收到如下错误:

TypeError: 无法读取未定义的属性“render”

如何确保脚本加载成功后调用componentDidMount()

【问题讨论】:

  • 如何加载脚本? &lt;script&gt; 标签?
  • @bejado 是的,仅针对此组件,因为我们需要它来自 cdn
  • 把你的应用和React脚本标签放在CDN脚本标签下面,这样浏览器就强制先加载render函数。
  • 在将脚本附加到文档正文时看起来有一个 onload 功能,因此您可以在组件的状态中使用布尔值来跟踪加载状态,并在 onload函数将状态的“已加载”布尔值设置为 true。然后在您的渲染函数中检查状态值。这是一个谷歌搜索:google.com.au/…*
  • 我已将其移至 index.html 以更安全。

标签: javascript reactjs react-redux


【解决方案1】:

根据React Component Specs and Lifecycle,我认为在 componentWillMount() 或 componentDidMount() 中加载脚本不是一个好主意。

下面的代码可能会对你有所帮助。

function new_script(src) {
  return new Promise(function(resolve, reject){
    var script = document.createElement('script');
    script.src = src;
    script.addEventListener('load', function () {
      resolve();
    });
    script.addEventListener('error', function (e) {
      reject(e);
    });
    document.body.appendChild(script);
  })
};
// Promise Interface can ensure load the script only once.
var my_script = new_script('http://example.com/aaa.js');

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      status: 'start'
    };
  }

  do_load = () => {
    var self = this;
    my_script.then(function() {
      self.setState({'status': 'done'});
    }).catch(function() {
      self.setState({'status': 'error'});
    })
  }

  render() {
    var self = this;
    if (self.state.status === 'start') {
      self.state.status = 'loading';
      setTimeout(function () {
        self.do_load()
      }, 0);
    }

    return (
      <div>{self.state.status}   {self.state.status === 'done' && 'here you can use the script loaded'}</div>
    );
  }
}

【讨论】:

  • 嗨,我有同样的问题,但我想调用一个引用第三方脚本的函数。当我使用 ReactJS 的构建命令时,它给了我一个错误,即未定义函数。我的脚本是“appform.autoconvert.co.uk/assets/js/iframe/…”而我想使用的函数是“initParentComms()”
  • 你能帮我解决这个问题吗
  • 如果外部脚本依赖于 redux store 中的某个值,这将不起作用。
猜你喜欢
  • 2017-10-20
  • 2018-09-25
  • 1970-01-01
  • 1970-01-01
  • 2019-04-08
  • 2021-05-15
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
相关资源
最近更新 更多