有没有办法从React 16门户获取ref
。我尝试了以下方法,但它似乎不起作用:
const Tooltip = props => (
ReactDOM.createPortal(
<div>{props.children}</div>,
// A DOM element
document.body
)
);
class Info extends React.Component {
render() {
return (
<Tooltip
ref={ el => this.tooltip = el }
>
My content
</Tooltip>
);
}
componentDidMount() {
console.log(this.tooltip); // undefined
}
}
我需要ref
才能动态计算元素最终位置!
答案 0 :(得分:6)
ReactDOM.createPortal
返回ReactPortal个实例,该实例是有效的ReactNode但不是有效的DOM元素。同时createPortal
将尊重组件上下文。所以我将函数调用移到了render方法中,它解决了这个问题。
class Info extends React.Component {
render() {
// I moved the portal creation to be here
return ReactDOM.createPortal(
// A valid DOM node!!
<div ref={ el => this.tooltip = el }>{props.children}</div>,
// A DOM element
document.body
);
}
componentDidMount() {
console.log(this.tooltip); // HTMLDivElement
}
}
答案 1 :(得分:1)
如果要使用挂钩,也可以
import { createPortal } from 'react-dom'
import React, { useRef } from 'react'
const Portal = ({ children }) => {
const portal = useRef(document.createElement('div'))
return createPortal(children, portal.current)
}
另外,在您的确切示例中,您将需要使用forwardRef
,因为如果没有refs
,则无法将其传递给孩子。
const Tooltip = forwardRef((props, ref) => (
createPortal(
<div ref={ref}>{props.children}</div>,
// A DOM element
document.body
)
));
const Info = () => {
const ref = useRef()
return (
<Tooltip ref={ref}>
My content
</Tooltip>
)
}
这最后一点未经测试,但是我很确定它会起作用。
答案 2 :(得分:0)
您需要在App组件中使用this.tooltip.props.children
并对Tooltip组件使用以下代码:
const appRoot = document.getElementById('app-root');
const tooltipRoot = document.getElementById('tooltip-root');
class Tooltip extends Component {
constructor(props) {
super(props);
// Create a div that we'll render the Tooltip into
this.el = document.createElement('div');
}
componentDidMount() {
// Append the element into the DOM on mount.
tooltipRoot.appendChild(this.el);
}
componentWillUnmount() {
// Remove the element from the DOM when we unmount
tooltipRoot.removeChild(this.el);
}
render() {
// Use a portal to render the children into the element
return ReactDOM.createPortal(
// Any valid React child: JSX, strings, arrays, etc.
this.props.children,
// A DOM element
this.el,
);
}
}
class App extends React.Component {
componentDidMount() {
console.log(this.tooltip.props.children);
}
render() {
return (
<div>
<Tooltip ref={ el => this.tooltip = el }>
My content
</Tooltip>
</div>
);
}
}
ReactDOM.render(<App />, appRoot);
基于Dan Abramov代码示例https://codepen.io/jorgemcdev/pen/aLYRVQ
的演示https://codepen.io/gaearon/pen/jGBWpE