我想直接在没有Target容器的情况下渲染组件,我需要在放置生成的JS文件的地方正确获取组件的内容。
这是我的index.js文件,我删除了“ document.getElementById('target-container')”,那里有一种方法可以在没有目标容器的情况下呈现此组件,或者可以在不插入目标容器的情况下追加目标容器在HTML模板文件中。
var React = require('react');
var ReactDOM = require('react-dom');
import axios from 'axios';
import '../node_modules/cleanslate/cleanslate.css';
import './style.scss';
class Widget extends React.Component {
constructor(props){
super(props);
this.state = {}
}
componentDidMount() {
let id = this.props.id;
axios.get(`https://api.com/${id}`)
.then((res) => {
const brand = res.data;
this.setState({
rating: brand.rating,
logo : brand.logo,
name: brand.name,
stars: brand.stars,
url: brand.url
});
});
}
render() {
return (
<div className="cleanslate">
<a href={this.state.url} target="_blank">
<img src="https://img/.svg" className="" alt="" />
<div className="rating-box">
<img src={this.state.logo} className="logo" alt={this.state.name} />
<span className="note">{this.state.rating}/10</span>
<div id="Selector" className={`selected-${this.state.stars}`}></div>
</div>
</a>
</div>
)
}
}
ReactDOM.render(
<Widget id="7182" />
)
以下是将组件附加到另一个示例中的示例(https://github.com/seriousben/embeddable-react-widget):
import React from 'react';
import ReactDOM from 'react-dom';
import Widget from '../components/widget';
import '../../vendor/cleanslate.css';
export default class EmbeddableWidget {
static el;
static mount({ parentElement = null, ...props } = {}) {
const component = <Widget {...props} />;
function doRender() {
if (EmbeddableWidget.el) {
throw new Error('EmbeddableWidget is already mounted, unmount first');
}
const el = document.createElement('div');
el.setAttribute('class', 'cleanslate');
if (parentElement) {
document.querySelector(parentElement).appendChild(el);
} else {
document.body.appendChild(el);
}
ReactDOM.render(
component,
el,
);
EmbeddableWidget.el = el;
}
if (document.readyState === 'complete') {
doRender();
} else {
window.addEventListener('load', () => {
doRender();
});
}
}
static unmount() {
if (!EmbeddableWidget.el) {
throw new Error('EmbeddableWidget is not mounted, mount first');
}
ReactDOM.unmountComponentAtNode(EmbeddableWidget.el);
EmbeddableWidget.el.parentNode.removeChild(EmbeddableWidget.el);
EmbeddableWidget.el = null;
}
}
答案 0 :(得分:1)
您可以在调用ReactDOM.render(例如,如here中所述的appendChild)之前,使用JS为您的应用生成容器,然后调用ReactDOM,将刚刚生成的元素作为容器传递。
UPD:
即使感觉很奇怪,您实际上也可以在调用ReactDOM.render
之前获得捆绑包的脚本标签。
知道这一点,您可以执行以下操作:
// Creates a container dynamically
let appContainer = document.createElement(`div`);
// Gets all <script>s on page and puts'em into an array.
let scriptTags = Array.from(document.getElementsByTagName(`script`));
// Filters scripts to find the one we need.
let targetScript = scriptTags.filter(
scriptTag => scriptTag.src === `https://example.com/bundle.js`
);
// Uh oh, we got either too many or too few,
// it might be bad, better stop right here.
if( targetScript.length !== 1 ) return;
// Inserts app container before the script.
document.body.insertBefore( appContainer, targetScript[0] );
// Renders things inside the container
ReactDOM.render (
<MyComponent />,
appContainer
);
即使上面的代码段可以按预期工作(我的测试通过了),但我不确定在生产环境中使用此代码是否安全。