这可能是一个愚蠢的问题。但实际上,我正在创建一个可在任何普通HTML / JS文件中使用的React Modal组件。我可以使用Webpack从React组件中创建一个bundle.js文件,然后可以将其注入Vanilla HTML文件的div标签中,如下所示:
<div id="my-modal-target"></div>
<script src="bundle.js"></script>
由于我正在尝试创建模式,所以发生的事情是,每当用户单击“退出”时,我的React组件将有条件地将模式隐藏。但是,我试图弄清楚如何通过单击目标Vanilla HTML文件中的按钮来重新加载React组件。我将对我应该如何进行提出任何建议。这是我尝试过的一些东西:
非常感谢您的帮助!
有多种方法可以完成React / non-React通信。
虽然每种方法都有优点和缺点,但是这是与框架无关的优点。您也可以对Vue组件和vanilla js执行相同的操作。缺点是您需要找到一种以干净的方式管理和记录事件的方法,否则您的应用程序可能很快变得难以维护。
在组件内部,您需要创建并监听自定义事件。然后,您可以从任何地方分派它,组件将捕获它并进行相应的更新。
const OPEN_EVENT_NAME = 'open';
const CLOSE_EVENT_NAME = 'close';
const container = document.querySelector('#app');
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: true,
}
// Bind the "open" and "close" events to their respective functions
container.addEventListener(OPEN_EVENT_NAME, this.openModal);
container.addEventListener(CLOSE_EVENT_NAME, this.closeModal);
}
openModal = () => {
this.setState({ open: true });
}
closeModal = () => {
this.setState({ open: false });
}
render() {
return (
<div>The modal is {this.state.open ? 'open' : 'closed'}</div>
)
};
}
ReactDOM.render(<App />, container);
// Create custom events
const openEvent = new Event(OPEN_EVENT_NAME);
const closeEvent = new Event(CLOSE_EVENT_NAME);
// Create events dispatchers
const openModal = () => container.dispatchEvent(openEvent);
const closeModal = () => container.dispatchEvent(closeEvent);
// Dispatch events on buttons click
document.querySelector('#open-btn').addEventListener('click', openModal);
document.querySelector('#close-btn').addEventListener('click', closeModal);
body {
font-family: 'system-ui';
padding: 12px;
}
h2 {
font-weight: bold;
margin: 0;
margin-bottom: 6px;
}
hr {
margin: 12px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<h2>
This is React
</h2>
<div id="app"></div>
<hr>
<h2>
This is not React
</h2>
<button id="open-btn">
Open modal
</button>
<button id="close-btn">
Close modal
</button>
引用通常用于访问React组件的底层DOM元素。
它们还可以用于将组件附加到窗口对象,从而访问其状态并公开其方法。
此方法不太容易出错,因为您使用与组件相同的语言(状态,方法等),但这也是不利的一面,因为这意味着您组件的最终用户对React有所了解,这可能并非如此。
这是方法,thanks to this article。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
open: true,
}
}
openModal = () => {
this.setState({ open: true });
}
closeModal = () => {
this.setState({ open: false });
}
render() {
return (
<div>The modal is {this.state.open ? 'open' : 'closed'}</div>
)
};
}
ReactDOM.render(<App ref={myComponent => window.myComponent = myComponent} />, document.querySelector('#app'));
body {
font-family: 'system-ui';
padding: 12px;
}
h2 {
font-weight: bold;
margin: 0;
margin-bottom: 6px;
}
hr {
margin: 12px 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<h2>
This is React
</h2>
<div id="app"></div>
<hr>
<h2>
This is not React
</h2>
<button onclick="window.myComponent.openModal()">
Open modal
</button>
<button onclick="window.myComponent.closeModal()">
Close modal
</button>
由于您正在使用React钩子,并且您无法引用功能组件,因此我不建议您使用方法2。
[我建立了一个迷你示例,说明如何实现方法1(使用事件与React进行通信)。
如上所述,这为最终用户提供了更好的API,并且可能是两者中最干净的解决方案。