在react中,this.state在函数中获得null状态

时间:2017-05-27 05:39:55

标签: reactjs

我想在悬停时更改backgroundColor但在onMouseOver函数调用时遇到错误它在控制台中显示“Uncaught TypeError:无法读取属性'setState'的null”。请让我知道这段代码有什么问题,谢谢。

import React from 'react'
import { Link } from 'react-router'
import { prefixLink } from 'gatsby-helpers'
import Helmet from 'react-helmet'
import { config } from 'config'

export default class Index extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
       header: "harry header",
       content: "content for harry",
       activeClass : 'normal',
       hovered :false
      }
   }
   componentDidMount(){
      var cssClass = 'normal';
      window.addEventListener('scroll', (event) => {
         if(event.srcElement.body.scrollTop == 0){
             cssClass = 'normal';
         }else{
             cssClass = 'fixed';
         }
         this.setState({
            activeClass: cssClass,
         })
      });
  }
  style() {
      if (this.state.hovered) {
        return { backgroundColor: "red" }
      } else {
        return { backgroundColor: "grey" }
      }
  }
  onMouseOver (){
      this.setState({ hovered:true });
  }
  onMouseOut (){
      this.setState({ hovered:false });
  }
  render() {
    return (
      <div>
        <header className={`header ${this.state.activeClass}`} >
          <div className="top-bar">
            <span><a href="tel:6788272782">678-827-2782 </a></span>
            <span><a href="mailto:hellohello@knotel.com"> hellohello@knotel.com</a></span>
            <button>Login</button>
          </div>
        </header>
        <div className="banner-main-outer">
          <div className="banner-main">
          </div>
          <div className="abs-height-caption">
            <div className="caption-banner">
              <div className="logo-main"><img src={require('../img/knotel.svg')}/></div>
              <h2>Commit to your business, not a lease</h2>
              <span>Headquarters as a Service</span>
              <button>Book a tour</button>
            </div>
            <ul className="kno-ul">
              <li><a>   LOCATIONS</a></li>
              <li><a>   SPACES</a></li>
              <li><a>   Services</a></li>
              <li><a>   Events</a></li>
              <li className="kno-hiring"><a>    We're hiring</a></li>
            </ul>
          </div>
          <div className="banner-btm-link">
            <a>Tenant Reps</a>
            <a>I have space</a>
          </div>
        </div>
        <div className="Spaces-Offer">
          <div className="header-bar">Our Locations</div>
          <div className="map-outer">
            <img src={require('../img/map.jpg')} />
          </div>
        </div>
        <div className="our-offer">
          <div className="header-bar">Spaces We Offer</div>
          <div onMouseOver={this.onMouseOver} 
                   onMouseOut={this.onMouseOut} 
                   style={this.style()} className="offer-cards">
            <ul>
              <li className="blue-block">
                <h1>Flexible Workspace For Growing Teams</h1>
                <p>We provide the resources so growing teams can focus their business. Many of our companies have graduated from coworking spaces.</p>
                <div className="offer-res-img" />
              </li>
              <li className="brown-block">
                <h1>Branded Floors for Established Companies</h1>
                <p>When you need your own floor we provide dedicated, branded space for your company with a backbone of Knotel management.</p>
                <div className="offer-res-img" />
              </li>
              <li className="purple-block">
                <h1>Flagship Buildings for World Leaders</h1>
                <p>When you are ready to take over the world, Knotel will take over a building for you. Turnkey commercial real estate at any size.</p>
                <div className="offer-res-img" />
              </li>
            </ul>
          </div>
        </div>
        <div className="our-services">
          <div className="header-bar">Services We Provide</div>
          <div className="sources-cards">
            <ul>
              <li className="active">
                <h1>Sourcing and Buildout</h1>
                <p>Knotel bundles property market insight with interior design expertise and buildout management, which ensures the client’s space vision is met on time, on budget, and without headaches.</p>
                <div className="sources-res-img" />
              </li>
              <li>
                <h1>Seamless Operations</h1>
                <p>Knotel provides comprehensive office services powered by domain experts and best of breed technology. Enjoy the highest ratio of conference rooms per person in the industry, and exclusive deals at a high quality set of partners</p>
                <div className="sources-res-img" />
              </li>
              <li>
                <h1>Flexible Terms</h1>
                <p>Knotel has a simple pricing structure with flexible terms. We offer various month to month and fixed term agreements tailored to your needs.</p>
                <div className="sources-res-img" />
              </li>
              <li>
                <h1>Events and Community</h1>
                <p>Knotels are vibrant spaces, with engaged communities and a strong roster of events. Enjoy office hours and informal access to like-minded industry professionals.</p>
                <div className="sources-res-img" />
              </li>
            </ul>
            <div className="source-img-change" />
          </div>
        </div>
        <div className="our-events">
          <div className="header-bar">Events we're hosting</div>
          <div className="form-contact">
            <div className="main-outer-inp">
              <h1>Stay in the know about Knotel events and news</h1>
              <div className="input-blocks">
                <input placeholder="First Name (required)" type="text" />
              </div>
              <div className="input-blocks">
                <input placeholder="Last Name (required)" type="text" />
              </div>
              <div className="input-blocks">
                <input placeholder="Email (required)" type="text" />
              </div>
            </div>
            <div className="sub-btn">
              <button>SUBSCRIBE</button>
            </div>
          </div>
        </div>
        <div className="structure-events">
          <div className="structure-container">
            <div className="events-details">
              <div className="events-knotels">COMING EVENTS</div>
              <ul>
                <li>
                  <div className="img-block"><img src={require('../img/manhattan-logo.jpg')} /></div>
                  <div className="eventdetail">
                    <div className="dates-on">
                      <span>07</span>
                      <p>Jun</p>
                    </div>
                    <div className="gtm-para">
                      <span>Entrepreneurship Council</span>
                      <p>8:30 am to 10:00 am at Knotel </p>
                    </div>
                  </div>
                </li>
                <li>
                  <div className="img-block"><img src={require('../img/Parrot Memento Knotel.png')} /></div>
                  <div className="eventdetail">
                    <div className="dates-on">
                      <span>14</span>
                      <p>Feb</p>
                    </div>
                    <div className="gtm-para">
                      <span>Knotel Private Founders Series</span>
                      <p>5:00 pm to 7:00 pm at Knotel Union Sq 1</p>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
            <div className="events-details">
              <div className="events-knotels">PAST EVENTS</div>
              <ul>
                <li>
                  <div className="img-block"><img src={require('../img/DLD2.jpg')} /></div>
                  <div className="eventdetail">
                    <div className="dates-on">
                      <span>12</span>
                      <p>May</p>
                    </div>
                    <div className="gtm-para">
                      <span>Future Of Cities - DLD NYC</span>
                      <p>8:00 am to 2:00 pm at Knotel Bryant </p>
                    </div>
                  </div>
                </li>
                <li>
                  <div className="img-block"><img src={require('../img/health.jpg')} /></div>
                  <div className="eventdetail">
                    <div className="dates-on">
                      <span>25</span>
                      <p>Apr</p>
                    </div>
                    <div className="gtm-para">
                      <span>Health Tech Founders' Stories</span>
                      <p>6:30 pm to 8:30 pm at Knotel Bryant</p>
                    </div>
                  </div>
                </li>
                <li>
                  <div className="img-block"><img src={require('../img/Space.jpg')} /></div>
                  <div className="eventdetail">
                    <div className="dates-on">
                      <span>20</span>
                      <p>Apr</p>
                    </div>
                    <div className="gtm-para">
                      <span>When Do We Go To Space?</span>
                      <p>6:30 pm to 8:30 pm at Knotel Bryant</p>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
        <footer>
          <div className="footer">
            <div className="img-footer">
              <img src={require('../img/knotel.svg')} />
            </div>
            <ul>
              <li><a>Careers</a></li>
              <li><a>Terms</a></li>
              <li><a>Tenant Reps</a></li>
              <li><a>I have space</a></li>
            </ul>
            <div className="Copyright-res">Copyright © 2017 KNOTEL. All rights reserved.</div>
          </div>
        </footer>
      </div>
    )
  }
}

3 个答案:

答案 0 :(得分:4)

来自docs

  

您必须小心JSX回调中this的含义。在JavaScript中,默认情况下,类方法不是bound。如果您忘记绑定this.handleClick并将其传递给onClick,则在实际调用该函数时this将为undefined

     

这不是特定于React的行为;它是how functions work in JavaScript的一部分。

因此,您需要将this绑定到您的方法,以使其正常工作 这就是构造函数的外观:

constructor(props) {
  super(props);
  this.state = {
   header: "harry header",
   content: "content for harry",
   activeClass: "normal",
   hovered: false
  }
  this.onMouseOver = this.onMouseOver.bind(this)
  this.onMouseOut = this.onMouseOut.bind(this)
}

答案 1 :(得分:2)

您需要将类方法绑定到<!DOCTYPE html> <html> <head> <title>ZeFrolity</title> <link rel="stylesheet" type="text/css" href="main.css"> </head> <body> <nav class="zeefro"> <img src="http://ambebajaj.com/app/webroot/img/uploads/Homeslider/1458125292bikeprod-img.png" width="100%" height="100%"> </nav> <nav class="bg-Main"> <img src="http://www.suttontrust.com/wp-content/uploads/2016/08/Coding.jpg" width="100%" height="100%"> </nav> <nav class="navClass"> <ul> <li><a href="">Contact Me</li></a> <li><a href="">Home</li></a> <li><a href="">About Me</li></a> <li><a href="">Portfolio <ul class="sub-menu"> <li><a href="">Logos</li></a> <li><a href="">Banners</li></a> <li><a href="">Twitch</li></a> <li><a href="">Youtube</li></a> </ul> </li> <li><a href="">Shop <ul class="sub-menu"> <li><a href="">Graphics</li></a> <li><a href="">Merch</li></a> </ul> </li> <li><a href="">Social Media <ul class="sub-menu"> <li><a href="">Twitch</li></a> <li><a href="">Youtube</li></a> <li><a href="">All</li></a> </ul> </li> </ul> </nav> </body> </html>实例。一种方法是在构造函数中 -

this

如果您收到错误,可以追溯到 constructor(props) { super(props); this.onMouseOver = this.onMouseOver.bind(this) this.onMouseOut = this.onMouseOut.bind(this) this.state = { header: "harry header", content: "content for harry", activeClass : 'normal', hovered :false } } ,其中cannot read property x of null应该是null,您知道this的绑定不正确调用方法/函数的时间。

答案 2 :(得分:0)

其他答案都是正确的,但您也可以将事件添加到更高的顺序<div>  

因此您可以将组件修改为

return (
  <div onMouseOut={this.onMouseOut} onMouseOver={this.onMouseOver}>
      ...
  </div>
);