[英]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.