Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.6k views
in Technique[技术] by (71.8m points)

React如何实现popover气泡卡片功能?

想用react实现类似antd的气泡卡片功能,但不知道怎么实现能同时将组件的子元素渲染出来,又能将气泡卡片的内容渲染在body中(React.createPortal可以将内容渲染到body中)。
popover.gif

要怎么才能实现上图这种效果呢?求大神指点


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

不要怀疑自己,我的校友,就是 React.createPortal()

挖了 antd 的坟,发现是 createPortal ,我还解决了这个问题:
?? 如何优雅地解决多个 React、Vue App 之间的状态共享?

文档:https://reactjs.org/docs/port...
demo:https://codepen.io/gaearon/pe...

更新————————————————————————————

// These two containers are siblings in the DOM
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() {
    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, show: false }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    // This will fire when the button in Child is clicked,
    // updating Parent's state, even though button
    // is not direct descendant in the DOM.
    this.setState((prevState) => ({
      clicks: prevState.clicks + 1,
      show: !prevState.show,
    }))
  }

  render() {
    return (
      <div onClick={this.handleClick}>
        <button>Open Modal</button>
        <p>Number of clicks: {this.state.clicks}</p>
        <p>
          Open up the browser DevTools to observe that the button is not a child of the div with the
          onClick handler.
        </p>

        {this.state.show ? (
          <Modal>
            <div className="modal">
              <p>Some contents...</p>
            </div>
          </Modal>
        ) : null}
      </div>
    )
  }
}

function Child() {
  // The click event on this button will bubble up to parent,
  // because there is no 'onClick' attribute defined
  return (
    <div className="modal">
      <button>Click</button>
    </div>
  )
}

ReactDOM.render(<Parent />, appRoot)

将上面代码粘贴至 https://codepen.io/gaearon/pe...
chrome-capture (14).gif


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...