diff --git a/src/Portal.js b/src/Portal.js index 58babf85..4d24e49c 100644 --- a/src/Portal.js +++ b/src/Portal.js @@ -7,7 +7,7 @@ export default class Portal extends React.Component { getContainer: PropTypes.func.isRequired, children: PropTypes.node.isRequired, didUpdate: PropTypes.func, - } + }; componentDidMount() { this.createContainer(); @@ -37,6 +37,11 @@ export default class Portal extends React.Component { render() { if (this._container) { + const currentContainer = this.props.getContainer(); + if (currentContainer && this._container !== currentContainer) { + this.removeContainer(); + this._container = currentContainer; + } return ReactDOM.createPortal(this.props.children, this._container); } return null; diff --git a/tests/container.test.js b/tests/container.test.js new file mode 100644 index 00000000..cbf77a1d --- /dev/null +++ b/tests/container.test.js @@ -0,0 +1,37 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import PortalWrapper from '../src/PortalWrapper'; + +describe('container', () => { + let div1; + let div2; + beforeAll(() => { + div1 = document.createElement('div'); + div1.id = 'dom1'; + div2 = document.createElement('div'); + div2.id = 'dom2'; + document.body.appendChild(div1); + document.body.appendChild(div2); + }); + afterAll(() => { + document.body.removeChild(div1); + document.body.removeChild(div2); + }); + it('Same function returns different DOM', async () => { + const wrapper = mount( + document.getElementById('dom1')} + > + {() =>
Content
} +
, + ); + + expect(document.querySelector('#dom1 #children')).not.toBeNull(); + + wrapper.setProps({ getContainer: () => document.getElementById('dom2') }); + + expect(document.querySelector('#dom1 #children')).toBeNull(); + expect(document.querySelector('#dom2 #children')).not.toBeNull(); + }); +});