以下是我实施的代码:
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {Link} from 'react-router'
import {Table, Column} from '../../Layout/components/Table'
import ReactDOM from 'react-dom'
// import ExternalPortal from '../../Sites/components/ExternalPortal'
export const TableName = 'ProjectDashboard'
class MyWindowPortal extends Component {
static propTypes = {
children: PropTypes.node,
closeWindowPortal: PropTypes.func
}
constructor (props) {
super(props)
this.containerEl = document.createElement('div') // STEP 1: create an empty div
this.externalWindow = null
}
componentDidMount () {
// STEP 3: open a new browser window and store a reference to it
this.externalWindow = window.open('', '', 'width=600,height=400')
// STEP 4: append the container <div> (that has props.children appended to it) to the body of the new window
this.externalWindow.document.body.appendChild(this.containerEl)
this.externalWindow.document.title = 'A React portal window'
// copyStyles(document, this.externalWindow.document)
// update the state in the parent component if the user closes the
// new window
this.externalWindow.addEventListener('beforeunload', () => {
this.props.closeWindowPortal()
})
}
componentWillUnmount () {
// This will fire when this.state.showWindowPortal in the parent component becomes false
// So we tidy up by just closing the window
this.externalWindow.close()
}
render () {
// STEP 2: append props.children to the container <div> that isn't mounted anywhere yet
return ReactDOM.createPortal(this.props.children, this.containerEl)
}
}
export default class ProjectTable extends Component {
constructor (props) {
super(props)
this.state={showWindowPortal:false}
this.toggleWindowPortal = this.toggleWindowPortal.bind(this)
this.closeWindowPortal = this.closeWindowPortal.bind(this)
}
static propTypes = {
data: PropTypes.object.isRequired,
loginId: PropTypes.string.isRequired
}
componentDidMount () {
window.addEventListener('beforeunload', () => {
this.closeWindowPortal()
})
}
toggleWindowPortal () {
this.setState({showWindowPortal: !this.state.showWindowPortal})
}
closeWindowPortal () {
this.setState({showWindowPortal: false})
}
render () {
return (
<div>
<div>
<p>This div is just for testing click here to see the portal</p>
{
this.state.showWindowPortal &&
(
<MyWindowPortal closeWindowPortal={this.closeWindowPortal}>
<button
onClick={() => this.closeWindowPortal()}
>
Close
</button>
</MyWindowPortal>
)
}
<button onClick={this.toggleWindowPortal}>
{this.state.showWindowPortal ? 'Close the' : 'Open a'} Portal
</button>
</div>
</div>
)
}
}
门户内的按钮在点击时不会触发任何内容。它根本不会发射。请注意,MyWindowPortal会打开一个新窗口,该按钮将在该窗口中呈现。尝试在Firefox和Chrome上测试它。我不确定我做错了什么。
我用onClick处理程序解决了同样的问题但在我的情况下我在WindowPortal中使用了组件。我对该问题的解决方法是使用ref和手动分配onclick事件处理程序到我在组件内部的每个按钮元素。这是片段示例:
class SomeComponent extends Component {
constructor(props) {
super(props);
this.ref = (element) => {
element.querySelector('button.one').onclick = () => {
alert( 'One!' );
}
element.querySelector('button.two').onclick = () => {
alert( 'Two!' );
}
}
}
render() {
return <div className="some-component" ref={this.ref}>
<button type='button' className='one'>Click One</button>
<button type='button' className='two'>Click Two</button>
</div>;
}
}
顺便说一句,我正在使用redux和SomeComponent成功连接到商店并允许调度操作。