我正在遵循升级到React 18的指南。完成升级后,我在应用程序的某些页面上看到错误。
ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported in React 18.
我没有在我的应用程序的任何地方使用unstable_renderSubtreeIntoContainer()
函数,但是当我仔细观察导致这些错误的原因时,它似乎导致了我的Bootstrap组件。
是否有办法更新这个以删除错误?
在升级到React 18后使用OverlayTrigger
组件时,我遇到了react-bootstrap@v0.33.1
同样的问题。警告消息建议迁移到使用门户。因此,我实现了一个利用门户的CustomOverlayTrigger
组件,并参考了React的门户文档来实现这一点。请注意,此解决方案适用于使用OverlayTrigger
的Bootstrap 3 (react-bootstrap v0.33.1)。后来的react-bootstrap版本似乎不再使用ReactDOM.unstable_renderSubtreeIntoContainer
了。如果您不能迁移到更高的版本(像我一样),这个解决方案将对这个用例有所帮助。我还没有彻底检查其他组件是否使用了不推荐的方法,但是方法可能是相同的。
首先,我复制了位于这里的OverlayTrigger
组件代码的原始源代码。您需要清理导入,并将utils函数createChainedFunction
包含到代码中。
然后我根据React的文档创建了一个门户包装器,看起来像这样:
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
const tooltipRoot = document.getElementById('tooltip-root');
class PortalWrapper extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement('div');
}
componentDidMount() {
tooltipRoot.appendChild(this.el);
}
componentWillUnmount() {
tooltipRoot.removeChild(this.el);
}
render() {
// eslint-disable-next-line react/destructuring-assignment
return ReactDOM.createPortal(this.props.children, this.el);
}
}
PortalWrapper.propTypes = {
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
};
export default PortalWrapper;
在顶部,您可以看到const tooltipRoot = document.getElementById('tooltip-root');
行,我只是在index.html
中在react应用程序的根div旁边添加了一个div,该div将作为我的门户的锚点。
然后,回到从react-bootstrap复制的CustomOverlayTrigger
组件中,我以以下方式编辑它:
删除对
this._overlay
和this._mountNode
的所有引用,因为PortalWrapper
现在管理挂载/卸载。所以我删除了componentDidMount()
,componentDidUpdate()
,componentWillUnmount()
和renderOverlay()
我修改了makeOverlay,使其结果被
PortalWrapper
包裹,所以它变成了以下内容:
makeOverlay(overlay, props) {
return (
<PortalWrapper>
<Overlay
{...props}
show={this.state.show}
onHide={this.handleHide}
target={this}
>
{overlay}
</Overlay>
</PortalWrapper>
);
}
- 最后,我将渲染方法的返回语句改为:
return (<>
{cloneElement(child, triggerProps)}
{this.makeOverlay(overlay, props)}
</>);
在此之后,我只需将所有对OverlayTrigger
的调用替换为CustomOverlayTrigger
,并且没有警告消息,我得到了相同的结果。