无法在尚未使用事件监听器安装的组件上调用setState

时间:2019-11-03 18:08:49

标签: javascript reactjs

我收到此警告:

  

警告:无法在尚未安装的组件上调用setState。这是一项禁止操作的操作,但可能表明您的应用程序中存在错误。而是直接分配给this.state或在Navbar组件中定义具有所需状态的state = {};类属性。

我创建了一个带有NavMin组件的Navbar组件,该组件仅在屏幕的宽度为11000或更小时才呈现。我认为这与使用componentDidMount和componentWillUnmount有关,但是我不确定如何正确使用它。我尝试在NavMin中使用componentWillUnmount,但收到此错误:

  

无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。

这是两个组成部分:

import  React, { Component } from 'react';
import { Link } from 'react-router-dom';
import bars from './Images/bars.png';
import './NavMini.css'

class NavMini  extends Component {

    componentWillUnmount(){

    }
    constructor(props){
    super(props)
        this.state = {
            showMenu: false 
        }

        this.showMenu = this.showMenu.bind(this)
        this.closeMenu = this.closeMenu.bind(this)
    }

  showMenu(event){
       event.preventDefault();

       this.setState({
           showMenu: true
       },
       () => {
           document.addEventListener('click', this.closeMenu);
       });
   }

   closeMenu(){
       this.setState({
           showMenu: false 
       }, () => {
           document.removeEventListener('click', this.closeMenu);
       })
   }

    render(){
        return(
            <div id="Navigation-mini"> 
            <button  onClick={this.showMenu} className="button-nav">
                 <img className="Mini-nav" src={bars} alt="nav-icon"/>
            </button>
            {
            this.state.showMenu
                ? (
                <div className="Navmenu">
                    <Link className="NavLink-mini" to='/'>Home</Link>
                    <Link className="NavLink-mini" to='/About'>About</Link>
                    <Link className="NavLink-mini" to='/Blog'>Blog</Link>
                    <Link className="NavLink-mini" to='/Contact'>Contact</Link>
                </div>
                )
                : (
                    null
                )
            }

         </div>
        )
    }
}

export default NavMini
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import Search from './Images/Search.png';
import Logo from './Images/Icon.png';
import NavMini from './NavMini'
import './NavBar.css';


class Navbar extends Component{
    constructor(props){
        super(props)

        let width = window.innerWidth;

        this.state = {
            show: false 
        }

        if(width < 1100){
            this.setState({
                show: true
            })
        }
    }

    render(){
    return (
        <div>
        <div id="Navigation">
            <div id="NavLogo">
                <Link to='/'><img id="CodeDestinee" src={Logo} alt="Logo" /></Link>
                    <h3 id="LogoName">Code <br/> Destinee</h3>
            </div>

            <div id="Navbar">
                <Link className="NavLink" to='/'>Home</Link>
                <Link className="NavLink" to='/About'>About</Link>
                <Link className="NavLink" to='/Blog'>Blog</Link>
                <Link className="NavLink" to='/Contact'>Contact</Link>
                <img className="NavLink" id="SearchIcon" src={Search} alt="Search-Icon" />
            </div>
        </div>

        { !this.state.show ? <NavMini /> : null } 
        </div>
    )
    }
}

export default Navbar

有人可以帮助我了解我在做什么错吗?

3 个答案:

答案 0 :(得分:2)

您在构造函数中使用this.setState,请将其更改为

Traceback (most recent call last):
  File "/sftp/paramiko_bot.py", line 10, in <module>
    ssh_client.connect(hostname=host_name, port=22, username=user_name, password=password)
  File "\Local\Programs\Python\Python37\lib\site-packages\paramiko\client.py", line 340, in connect
    to_try = list(self._families_and_addresses(hostname, port))
  File "\Local\Programs\Python\Python37\lib\site-packages\paramiko\client.py", line 204, in _families_and_addresses
    hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM
  File "\AppData\Local\Programs\Python\Python37\lib\socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed

答案 1 :(得分:0)

如上所述,您正在构造函数中调用setState,而您不应该这样做。上述解决方案可能有效,但我相信更好的解决方案是在一个表达式中根据宽度将this.state = { show: width < 1100 } 设置为true或false:

this.state.show

这将根据宽度将{{1}}设置为true或false。

答案 2 :(得分:0)

componentDidMount() {
  let width = window.innerWidth;
  if(width < 1100){
      this.setState({
          show: true
      })
  }
}

构造函数是唯一应直接分配this.state的地方。在所有其他方法中,您需要改用this.setState()