我有一个站点,其中包含许多可以从任何地方打开的模式(例如LoginModal
)。我遇到的挑战是,如果我使用ReactDOM.render
之类的程序打开一个程序,那么在卸载父组件而不将其(以及所有可能的模态)放到模板中的情况下,如何自动清理它。>
例如,打开它的方法如下:
openLoginModal() {
ReactDOM.render(<LoginModal />, document.body);
}
LoginModal
可以在关闭时自行清理。但是,如果从打开它的组件中删除了DOM,我该如何让LoginModal
也知道要卸载。
我曾经想到的是使用Rx.Subject通知何时卸载,但这听起来像是一种错误的方法以及可能的反模式。
例如:
// modules/User.js
openLoginModal(unmountSubj) {
const container = document.createElement('div');
ReactDOM.render(<LoginModal />, container);
unmountSubj.subscribe(() => {
ReactDOM.unmountComponentAtNode(container);
});
}
// components/RandomView.jsx
unmountSubject = new Rx.Subject();
componentWillUnmount() {
this.unmountSubject.next();
}
login() {
User.openLoginModal(this.unmountSubject);
}
我想避免在每个可能使用的JSX模板中包含所有可能的模态组件。
您将如何处理?
答案 0 :(得分:0)
在我当前的React项目中,我已经通过使用多层组件架构解决了这个问题。
<App>
// the standard starting point for React apps
<DataLayer>
// this is where I make API calls for data that is shared between all components
<DisplayLayer>
// this is where I put the methods to launch display elements that are shared
// by all components (e.g., modals, alerts, notifications, etc.)
<Template>
// this is the first layer that is actually outputting HTML content
<ModuleX>
<ModuleY>
<ModuleZ>
// these modules control the main display area of the screen, they encompass
// major UI functions (e.g., UsersModule, TeamsModule, etc.)
// when one of these modules needs to launch a shared UI element (like a
// modal), they call a method in the <DisplayLayer> template - this means
// that if I have a commonly-used modal (like, LoginModal), it doesn't need
// to be included in every one of the core modules where someone might need
// to initiate a login; these modules are mounted-and-unmounted as the user
// navigates through the app
因此,当应用程序加载时,<App>
,<DataLayer>
,<DisplayLayer>
和<Template>
都会全部加载(它们只会加载一次)。当用户四处浏览时,<ModuleX/Y/Z/etc>
组件已安装和卸载,但是所有“常见内容”都保留在应用程序较高层中已安装/加载的位置。
答案 1 :(得分:0)
到目前为止,这是我想出的解决方案:这里有一个模式管理器模块,它将模块(通过ReactDOM.render
呈现到DOM中,并返回一个将其卸载的函数。
这是简化版:
// modalManager.js
export default modalManager = {
openModal(modalClass, props) {
// Create container for the modal to be rendered into
const renderContainer = document.createElement('div');
document.body.appendChild(renderContainer);
// Create & render component
const modalInst = React.createElement(modalClass, { ...props, renderContainer });
ReactDOM.render(modalInst, renderContainer);
// Return unmounting function
return () => this.unmountModal(renderContainer);
},
unmountModal(renderContainer) {
ReactDOM.unmountComponentAtNode(renderContainer);
renderContainer.parentNode.removeChild(renderContainer);
},
}
// TestThing.jsx
class TestThing extends React.Component {
unmountLogin = null;
componentWillUnmount() {
this.unmountLogin();
}
login() {
this.unmountLogin = modalManager.openModal(Login, {});
}
}
您还将注意到renderContainer
被传递给模式组件。这样,模态可以在关闭时调用modalManager.unmountModal
本身。
让我知道您的想法。