Portals

Portals

Portals 提供了一种很好的将子节点渲染到父组件以外的 DOM 节点的方式。

const appRoot = document.getElementById('app-root');
//找一个modal入口挂载点
const modalRoot = document.getElementById('modal-root');


class Modal extends React.Component {
  constructor(props) {
    super(props);
    //创建组件容器
    this.el = document.createElement('div');
  }

  componentDidMount() {
    //dom渲染好,将modal容器加入到modalRoot里面
    modalRoot.appendChild(this.el);
  }

  componentWillUnmount() {
    //组件销毁到时候删除掉modal容器
    modalRoot.removeChild(this.el);
  }
  
  render() {
    //使用createPortal指定挂载位置
    return ReactDOM.createPortal(
        //接收组件
      this.props.children,
      //将组件加入到modal容器里
      this.el,
    );
  }
}


class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {showModal: false};
    
    this.handleShow = this.handleShow.bind(this);
    this.handleHide = this.handleHide.bind(this);
  }

  handleShow() {
    this.setState({showModal: true});
  }
  
  handleHide() {
    this.setState({showModal: false});
  }

  render() {
    const modal = this.state.showModal ? (
      <Modal>
        //传入组件内容
        <div className="modal">
          <div>
            With a portal, we can render content into a different
            part of the DOM, as if it were any other React child.
          </div>
          This is being rendered inside the #modal-container div.
          <button onClick={this.handleHide}>Hide modal</button>
        </div>
      </Modal>
    ) : null;

    return (
      <div className="app">
        This div has overflow: hidden.
        <button onClick={this.handleShow}>Show modal</button>
        {modal}
      </div>
    );
  }
}

ReactDOM.render(<App />, appRoot);


原文地址:https://www.cnblogs.com/pluslius/p/10198155.html