jiy*_*ong 49 javascript modal-dialog css-transitions reactjs
这个答案中有一个模态/sf/answers/1875236261/,它通过附加它来创建一个基于React的模态<body>.但是,我发现它与React提供的转换插件不兼容.
如何创建一个有过渡(在进入和离开期间)?
Gil*_*man 62
在2015年的反应中,Ryan Florence 展示了使用门户网站.这是你如何创建一个简单的Portal组件......
var Portal = React.createClass({
render: () => null,
portalElement: null,
componentDidMount() {
var p = this.props.portalId && document.getElementById(this.props.portalId);
if (!p) {
var p = document.createElement('div');
p.id = this.props.portalId;
document.body.appendChild(p);
}
this.portalElement = p;
this.componentDidUpdate();
},
componentWillUnmount() {
document.body.removeChild(this.portalElement);
},
componentDidUpdate() {
React.render(<div {...this.props}>{this.props.children}</div>, this.portalElement);
}
});
Run Code Online (Sandbox Code Playgroud)
然后你可以在React中做的一切你可以在门户网站内做...
<Portal className="DialogGroup">
<ReactCSSTransitionGroup transitionName="Dialog-anim">
{ activeDialog === 1 &&
<div key="0" className="Dialog">
This is an animated dialog
</div> }
</ReactCSSTransitionGroup>
</Portal>
Run Code Online (Sandbox Code Playgroud)
你也可以看看Ryan的react-modal,虽然我还没有真正使用它,所以我不知道它对动画的效果如何.
mpe*_*pen 23
这是本文中描述的方法的ES6版本:
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
export default class BodyEnd extends React.PureComponent {
static propTypes = {
children: PropTypes.node,
};
componentDidMount() {
this._popup = document.createElement('div');
document.body.appendChild(this._popup);
this._render();
}
componentDidUpdate() {
this._render();
}
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(this._popup);
document.body.removeChild(this._popup);
}
_render() {
ReactDOM.render(this.props.children, this._popup);
}
render() {
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
只需将您想要的任何元素包装在DOM的末尾:
<BodyEnd><Tooltip pos={{x,y}}>{content}</Tooltip></BodyEnd>
Run Code Online (Sandbox Code Playgroud)
这是React 16的更新版本:
import React from 'react';
import ReactDOM from 'react-dom';
export default class BodyEnd extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
this.el.style.display = 'contents'; // The <div> is a necessary container for our content, but it should not affect our layout. Only works in some browsers, but generally doesn't matter since this is at the end anyway. Feel free to delete this line.
}
componentDidMount() {
document.body.appendChild(this.el);
}
componentWillUnmount() {
document.body.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el,
);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 9
正如其他答案所述,这可以使用门户网站完成.从v16.0 门户网站开始包含在React中.
<body>
<div id="root"></div>
<div id="portal"></div>
</body>
Run Code Online (Sandbox Code Playgroud)
通常,当您从组件的render方法返回一个元素时,它会作为最近父节点的子节点挂载到DOM中,但是通过门户,您可以将子节点插入DOM中的其他位置.
const PortalComponent = ({ children, onClose }) => {
return createPortal(
<div className="modal" style={modalStyle} onClick={onClose}>
{children}
</div>,
// get outer DOM element
document.getElementById("portal")
);
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
modalOpen: false
};
}
render() {
return (
<div style={styles}>
<Hello name="CodeSandbox" />
<h2>Start editing to see some magic happen {"\u2728"}</h2>
<button onClick={() => this.setState({ modalOpen: true })}>
Open modal
</button>
{this.state.modalOpen && (
<PortalComponent onClose={() => this.setState({ modalOpen: false })}>
<h1>This is modal content</h1>
</PortalComponent>
)}
</div>
);
}
}
render(<App />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)
在这里查看工作示例.