[英]How to get ref from a React 16 portal?
有没有办法从 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
才能动态计算元素的最终位置!
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
}
}
如果你想用钩子来做,你也可以这样做
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>
)
}
最后一点没有经过测试,但我很确定它会起作用。
您需要在 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);
工作演示https://codepen.io/jorgemcdev/pen/aLYRVQ ,基于 Dan Abramov 代码示例https://codepen.io/gaearon/pen/jGBWpE
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.