2017-05-07 96 views
2

我已经经历的理论家“构建第一个生产质量作出反应的应用程序”和一切都会很好,直到第17课,你应该在哪里使用context创建自己自制的特性“语境”路由器组件。至于我可以告诉大家,我做同样的事情在课,但是当我点击Link组件之一,我得到这个控制台错误:无法读取空

Link.js:11 Uncaught TypeError: Cannot read property 'context' of null 
at handleClick (http://localhost:3000/static/js/bundle.js:33792:12) 
at Object.ReactErrorUtils.invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:17162:17) 
at executeDispatch (http://localhost:3000/static/js/bundle.js:16945:22) 
at Object.executeDispatchesInOrder (http://localhost:3000/static/js/bundle.js:16968:6) 
at executeDispatchesAndRelease (http://localhost:3000/static/js/bundle.js:16356:23) 
at executeDispatchesAndReleaseTopLevel (http://localhost:3000/static/js/bundle.js:16367:11) 
at Array.forEach (native) 
at forEachAccumulated (http://localhost:3000/static/js/bundle.js:17265:10) 
at Object.processEventQueue (http://localhost:3000/static/js/bundle.js:16570:8) 
at runEventQueueInBatch (http://localhost:3000/static/js/bundle.js:24192:19) 

该路段组件看起来像这样:

import React, { Component } from 'react'; 

export class Link extends Component { 
    static contextTypes = { 
    route: React.PropTypes.string, 
    linkHandler: React.PropTypes.func, 
    } 

    handleClick(e) { 
    e.preventDefault(); 
    this.context.linkHandler(this.props.to) 
    } 

    render() { 
    const activeClass = this.context.route === this.props.to ? 'active' : ''; 
    return <a href="#" className={activeClass} onClick={this.handleClick}>{this.props.children}</a> 
    } 
} 

Link.propTypes = { 
    to: React.PropTypes.string.isRequired 
} 

和路由器组成部分看起来像这样:

import React, { Component } from 'react'; 

const getCurrentPath =() => { 
    const path = document.location.pathname; 
    return path.substring(path.lastIndexOf('/')); 
} 

export class Router extends Component { 
    state = { 
    route: getCurrentPath() 
    } 

    handleLinkClick = (route) => { 
    this.setState({ route }); // same as { route: route } 
    history.pushState(null, '', route); 
    } 

    static childContextTypes = { 
    route: React.PropTypes.string, 
    linkHandler: React.PropTypes.func, 
    }; 

    getchildContext() { 
    return { 
     route: this.state.route, 
     linkHandler: this.handleLinkClick, 
    }; 
    } 

    render() { 
    return <div>{this.props.children}</div> 
    } 
} 

的这可能是导致该问题的任何想法?

感谢在正确的方向上没有任何指针!

编辑:

后跟随我的意见,我在构造函数约束​​(带箭头的功能相同的结果),并证实了预期的函数被调用,但现在我得到(谢谢!)一个不同的错误:

Uncaught TypeError: this.context.linkHandler is not a function 
at Link.handleClick (http://localhost:3000/static/js/bundle.js:33707:21) 
at Object.ReactErrorUtils.invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:17162:17) 
at executeDispatch (http://localhost:3000/static/js/bundle.js:16945:22) 
at Object.executeDispatchesInOrder (http://localhost:3000/static/js/bundle.js:16968:6) 
at executeDispatchesAndRelease (http://localhost:3000/static/js/bundle.js:16356:23) 
at executeDispatchesAndReleaseTopLevel (http://localhost:3000/static/js/bundle.js:16367:11) 
at Array.forEach (native) 
at forEachAccumulated (http://localhost:3000/static/js/bundle.js:17265:10) 
at Object.processEventQueue (http://localhost:3000/static/js/bundle.js:16570:8) 
at runEventQueueInBatch (http://localhost:3000/static/js/bundle.js:24192:19) 
+1

你需要把它绑定到handleClick。您可以在构造函数或的onClick做到这一点(不推荐)。 onClick = {this.handleClick.bind(this)}。或者为handleClick使用箭头函数。 const handleClick =()=> {}。 –

+0

^^这是回答提出的问题。 – Jason

回答

0

这是您在将ES6与React一起使用时的常见问题。您需要将handleClick函数绑定到React组件的上下文中。您可以使用箭头功能的组件定义绑定像上下文中

export class Link extends Component { 
    static contextTypes = { 
    route: React.PropTypes.string, 
    linkHandler: React.PropTypes.func, 
    } 

    handleClick = (e) => { 
    e.preventDefault(); 
    this.context.linkHandler(this.props.to) 
    } 

    render() { 
    const activeClass = this.context.route === this.props.to ? 'active' : ''; 
    return <a href="#" className={activeClass} onClick={this.handleClick}>{this.props.children}</a> 
    } 
} 

,或者您可以在次构造结合它像

export class Link extends Component { 
    constructor(props) { 
     super(props); 
     this.handleClick = this.handleClick.bind(this); 
    } 

    ... 

} 

,或者你可以在当时将它绑定调用

onClick={() => this.handleClick()}> 

or 

onClick={this.handleClick.bind(this)} 
0

除了需要将函数绑定到this之外,如果绑定了一个不再存在于该类中的函数,也会发生此错误:

export class Example extends Component { 
    constructor(props) { 
     super(props); 
     this.functionDoesNotExistAnymore = this.functionDoesNotExistAnymore.bind(this); 
    } 

    // functionDoesNotExistAnymore() {} 
} 
0

为了给这个问题一个明确的答案,其他人有很多额外的信息可能导致你误入歧途。

报价

You need to bind this to handleClick. You can either do this in a constructor or in onClick (not recommended). onClick={this.handleClick.bind(this)} . Or use an arrow function for handleClick. const handleClick =() = > { }.

- Norm Crandall(从评论)