在升级到React 18时,是否有办法修复由Bootstrap引起的错误?



我正在遵循升级到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组件中,我以以下方式编辑它:

  1. 删除对this._overlaythis._mountNode的所有引用,因为PortalWrapper现在管理挂载/卸载。所以我删除了componentDidMount(),componentDidUpdate(),componentWillUnmount()renderOverlay()

  2. 我修改了makeOverlay,使其结果被PortalWrapper包裹,所以它变成了以下内容:

makeOverlay(overlay, props) {
return (
<PortalWrapper>
<Overlay
{...props}
show={this.state.show}
onHide={this.handleHide}
target={this}
>
{overlay}
</Overlay>
</PortalWrapper>
);
}
  1. 最后,我将渲染方法的返回语句改为:
return (<>
{cloneElement(child, triggerProps)}
{this.makeOverlay(overlay, props)}
</>);

在此之后,我只需将所有对OverlayTrigger的调用替换为CustomOverlayTrigger,并且没有警告消息,我得到了相同的结果。

最新更新