2017-05-07 95 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(從評論)