Day363:举例说明 React 的插槽有哪些运用场景?你有用过 React 的插槽(Portals)吗?怎么用?
Genzhen opened this issue · 0 comments
Genzhen commented
每日一题会在下午四点在交流群集中讨论,五点小程序中更新答案
欢迎大家在下方发表自己的优质见解二维码加载失败可点击 小程序二维码
扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。
Portals
插槽(Portals)能将子节点渲染到父组件的 DOM 层次之外。
应用场景
当父组件有 overflow: hidden 或 z-index 样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框。
具体使用
ReactDOM.createPortal(child, container);
- 第一个参数 child 是任何可渲染的 React 子元素,例如一个元素,字符串或片段(fragment)。
- 第二个参数 container 则是一个 DOM 元素
render() {
// React 并*没有*创建一个新的 div。它只是把子元素渲染到 `domNode` 中。
// `domNode` 是一个可以在任何位置的有效 DOM 节点。
return ReactDOM.createPortal(
this.props.children,
domNode
);
}
具体应用示例
实现一个全局浮层:
- html
<body>
<div id="app-root"></div>
<div id="mask-root"></div>
</body>
-css
#modal-root {
position: relative;
z-index: 999;
}
.modal {
color: #fff;
background-color: rgba(0, 0, 0, 1);
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
- react
const appRoot = document.getElementById('app-root');
const maskRoot = document.getElementById('mask-root');
class Mask extends React.Component{
constructor(props){
super(props);
this.el = document.createElement('div');
}
componentDidMount()){
maskRoot.appendChild(this.el);
}
componentWillUnmount(){
maskRoot.removeChild(this.el);
}
render(){
return ReactDom.createPortal(
this.props.children,
this.el
)
}
}
class App extends React.Component{
constructor(props){
super(props);
this.state = {
showMask:false
}
this.handler = this.handler.bind(this);
}
handler(){
let showMask = this.state.showMask;
this.setState({showMask:true})
}
render(){
let showMask = this.state.showMask;
let mask = showMask ?
<Mask>
<div className="modal">
测试
<button onClick={this.handler}>hidden</button>
</div>
</Mask>
:null;
return (
<div>
this div has overflow:hidden.
<button onClick={this.handler}>show</button>
{mask}
</div>
)
}
}
ReactDOM.render(<App />,appRoot);