我正在尝试使用ReactJS嵌入Gist,但出现以下错误:
无法在“文档”上执行“写入”:无法从异步加载的外部脚本写入文档,除非已将其明确打开。
这是我的组件:
var EmbeddedGist = React.createClass({ render: function() { return ( <div id="gist-container" /> ); }, componentDidMount: function() { var src = this.props.srcUrl + ".js"; $('#gist-container').html('<script src="' + src + '"></script>'); } });
我从另一个组件中调用它,例如:
<EmbeddedGist srcUrl="https://gist.github.com/awalGarg/a5bd02978cecf3703f61" />
关于如何进行这项工作的任何想法?
Gist嵌入脚本用于document.write将构成嵌入式Gist的HTML编写到文档的HTML中。但是,当您的React组件添加script标签时,将其写入文档为时已晚。
document.write
script
虽然您无法将Gist嵌入脚本动态添加到页面中,但是您 可以 通过JSONP 获得Gist 的 内容 并将其自己写入文档中。这是一个具有gist属性和可选file属性并为您呈现要点的组件。
gist
file
var EmbeddedGist = React.createClass({ propTypes: { gist: React.PropTypes.string.isRequired, // e.g. "username/id" file: React.PropTypes.string // to embed a single specific file from the gist }, statics: { // Each time we request a Gist, we'll need to generate a new // global function name to serve as the JSONP callback. gistCallbackId: 0, nextGistCallback: function() { return "embed_gist_callback_" + EmbeddedGist.gistCallbackId++; }, // The Gist JSON data includes a stylesheet to add to the page // to make it look correct. `addStylesheet` ensures we only add // the stylesheet one time. stylesheetAdded: false, addStylesheet: function(href) { if (!EmbeddedGist.stylesheetAdded) { EmbeddedGist.stylesheetAdded = true; var link = document.createElement('link'); link.type = "text/css"; link.rel = "stylesheet"; link.href = href; document.head.appendChild(link); } } }, getInitialState: function() { return { loading: true, src: "" }; }, componentDidMount: function() { // Create a JSONP callback that will set our state // with the data that comes back from the Gist site var gistCallback = EmbeddedGist.nextGistCallback(); window[gistCallback] = function(gist) { if (this.isMounted()) { this.setState({ loading: false, src: gist.div }); EmbeddedGist.addStylesheet(gist.stylesheet); } }.bind(this); var url = "https://gist.github.com/" + this.props.gist + ".json?callback=" + gistCallback; if (this.props.file) { url += "&file=" + this.props.file; } // Add the JSONP script tag to the document. var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; document.head.appendChild(script); }, render() { if (this.state.loading) { return <div>loading...</div>; } else { return <div dangerouslySetInnerHTML={{__html: this.state.src}} />; } } });
您可以像这样使用它:
var app = ( <div> <EmbeddedGist gist="BinaryMuse/a57ae1a551472e06b29a" file="restful.js" /> <hr /> <EmbeddedGist gist="BinaryMuse/bb9f2cbf692e6cfa4841" /> </div> ); React.render(app, document.getElementById("container"));
看看这个在JSfiddle上工作的示例:http : //jsfiddle.net/BinaryMuse/nrb6zxfw/
改善此问题的一种方法是,确保EmbeddedGist已更改其属性gist或file属性的现有组件将通过挂接到来更新以使用新数据componentWillReceiveProps。
EmbeddedGist
componentWillReceiveProps