react 新API ——Portals
1.findDOMNode场景使用
在我们开发中往往会遇到一些获取真实DOM的情形,比如说 我要给一个div 通过滚轮事件方法或者缩小,此时我们就想到findDOMNode 来获取真实dom,可指定到具体某一个div或者img 等等标签~~~
代码:
定义鼠标滚轮事件
onMouseWheel = e => {
let dom = document.getElementById('nowWarningContent')
let ele = rdom.findDOMNode(dom);
if (ele.id==='nowWarningContent') {
this.updateMapParams({
scale: this.state.mapParams.scale + (e.deltaY > 0 ? -0.2 : +0.2)
});
}
};
2.Portals 场景使用
在我们网络停网的时候,需要给用户一个永久式的弹窗,一旦有网时,去除这个弹窗。
代码如下:
window.addEventListener('online', updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
此处来监听网络是否通常!
当没有网络的时候:
// 在 DOM 中有两个容器是兄弟级 (siblings)
const appRoot = document.getElementById('app-root');
const modalRoot = document.getElementById('modal-root');
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
// 在 Modal 的所有子元素被挂载后,
// 这个 portal 元素会被嵌入到 DOM 树中,
// 这意味着子元素将被挂载到一个分离的 DOM 节点中。
// 如果要求子组件在挂载时可以立刻接入 DOM 树,
// 例如衡量一个 DOM 节点,
// 或者在后代节点中使用 ‘autoFocus’,
// 则需添加 state 到 Modal 中,
// 仅当 Modal 被插入 DOM 树中才能渲染子元素。
modalRoot.appendChild(this.el);
}
componentWillUnmount() {
modalRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(
this.props.children,
this.el,
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {clicks: 0};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
// 当子元素里的按钮被点击时,
// 这个将会被触发更新父元素的 state,
// 即使这个按钮在 DOM 中不是直接关联的后代
this.setState(state => ({
clicks: state.clicks + 1
}));
}
render() {
return (
<div>
<p>Number of clicks: {this.state.clicks}</p>
<p>
测试一个新的API 功能点!
</p>
<Modal >
<Child add={this.handleClick} / >
</Modal>
</div>
);
}
}
function Child(props) {
// 这个按钮的点击事件会冒泡到父元素
// 因为这里没有定义 'onClick' 属性
return (
<div className="modal">
当前无网络,请检查网线链接
<button onClick={()=>{props.add()}}>关闭</button>
</div>
);
}
ReactDOM.render(<Parent />, appRoot);