javascript - React 16:错误:无法在未安装的组件上找到节点
问题描述
我最近将我的项目从 React v15.2.1 升级到 16.4.1,我的侧边栏组件抛出以下错误:
Error: Unable to find node on an unmounted component. bundle.js line 1326 > eval:42:15
invariant
webpack:///./node_modules/fbjs/lib/invariant.js?:42:15
findCurrentFiberUsingSlowPath
webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:3817:7
findCurrentHostFiber
webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:3886:23
findHostInstance
webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:16824:19
findDOMNode
webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:17310:12
handleClickOutside
webpack:///./src/components/simulator/sidebar/Sidebar.js?:99:31
handleClickOutside self-hosted:984:17
根据错误消息,我相信在 handleClickOutside(event) 方法中调用 ReactDOM.findDOMNode(this) 时会发生错误。
我正在使用的组件可以在这里找到:https://ashiknesin.com/blog/build-custom-sidebar-component-react/,我已经将其更改为:
import React from 'react'
import ReactDOM from 'react-dom'
import classNames from 'classnames'
import SimulatorForm from './SimulatorForm'
import './Sidebar.scss'
const openForm = require('../../../public/icons/si-glyph-arrow-left.svg');
const closeForm = require('../../../public/icons/si-glyph-arrow-right.svg');
const pinForm = require('../../../public/icons/si-glyph-pin-location-love.svg');
const unpinForm = require('../../../public/icons/si-glyph-pin-location-delete.svg');
class Sidebar extends React.Component {
constructor(props) {
super(props)
this.state = {
showMenu: false,
isMenuPinned: false,
formIcon: openForm,
pinIcon: pinForm,
modelsDescription: props.modelsDescription
}
// Methods to pin/unpin the Form
this.toggleMenu = this.toggleMenu.bind(this)
this.pinMenu = this.pinMenu.bind(this)
// Handlers
this.handleSelectedModelChange = this.props.handleSelectedModelChange
this.handleNewMasterGraphsData = this.props.handleNewMasterGraphsData
this.handleNewResults = this.props.handleNewResults
}
componentWillReceiveProps(nextProps) {
this.setState({ modelsDescription: nextProps.modelsDescription});
}
componentDidMount() {
document.addEventListener('click', this.handleClickOutside.bind(this), true);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside.bind(this), true);
}
pinMenu() {
this.setState({
isMenuPinned: !this.state.isMenuPinned,
pinIcon: this.state.isMenuPinned ? pinForm : unpinForm
});
}
toggleMenu() {
this.setState({
showMenu: !this.state.showMenu,
formIcon: this.state.showMenu ? openForm : closeForm
});
}
handleClickOutside(event) {
if (!this.state.isMenuPinned) {
const domNode = ReactDOM.findDOMNode(this);
if ((!domNode || !domNode.contains(event.target))) {
this.setState({
showMenu: false,
formIcon: openForm
});
}
}
}
render() {
const showMenu = this.state.showMenu;
const sidebarClass = classNames({
'sidebar': true,
'sidebar-menu-expanded': showMenu,
'sidebar-menu-collapsed': !showMenu
});
const elementsClass = classNames({
'expanded-element': true,
'is-hidden': !showMenu,
});
return (
<nav className={sidebarClass}>
<img className="menuIcon" src={this.state.formIcon} height="42" width="42" onClick={this.toggleMenu} />
<ul>
<li>
{
this.state.showMenu ? <img className="pinIcon" src={this.state.pinIcon} height="42" width="42" onClick={this.pinMenu} /> : null
}
</li>
<li>
{
this.state.showMenu ? <SimulatorForm modelsDescription={this.state.modelsDescription} handleSelectedModelChange={this.handleSelectedModelChange}
handleNewMasterGraphsData={this.handleNewMasterGraphsData} handleNewResults={this.handleNewResults} /> : null
}
</li>
</ul>
</nav>
)
}
}
export default Sidebar
最后,仅当我重新加载页面时才会引发错误。如果我不这样做,它似乎工作得很好。您是否有任何建议或建议以确保不会再次引发错误?
我一直在在线阅读有关此内容的信息,但找不到解决方法。另外,我不认为这被列为重大更改,但我可能是非常错误的。
解决方案
好的,由于代码的原始作者的帮助,我最终找到了解决方案。链接可以在这里找到。这是我绑定的问题,有关链接的更多详细信息。
所以,这就是我所做的。我改变了:
componentDidMount() {
document.addEventListener('click', this.handleClickOutside.bind(this), true);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside.bind(this), true);
}
至
componentDidMount = () => {
document.addEventListener("click", this.handleClickOutside, true);
};
componentWillUnmount = () => {
document.removeEventListener("click", this.handleClickOutside, true);
};
推荐阅读
- android - AlphaAnimation 在 KitKat 中旋转 Framelayout
- azure - 如何在 Azure Data Factory V2 中针对现有 Azure VM 运行远程命令(powershell/bash)?
- flutter - 等待阅读文档然后设置监听器?
- python - 获取文件执行模块代码的当前路径
- php - 获取mysql更新成功的确认
- php - Docker 安装 cURL 失败(需要 7.10.5 或更高版本)
- sql - 如何将 PostgreSQL 的`::FLOAT` 翻译成 MariaDB
- google-apps-script - 在复制到新工作表之前如何检查单元格是否为空?
- python - 在图像上查找图像
- sql - ORACLE SQL Group By STILL 给 Duplicates