2017-05-07 18 views
2

私はEggheadを "最初の制作品質のリアクションアプリを構築"しています。レッスン17まで、すべてがうまくいっています。contextを使用して自宅を作りますルータコンポーネント。私の知る限り、私は授業中とまったく同じことを行うが、私はLinkコンポーネントのいずれかをクリックしたときに、私はこのコンソールのエラーを取得:nullのプロパティ 'context'を読み取ることができません

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> 
    } 
} 

問題を引き起こして何ができるかの任意のアイデア?

正しい方向のポインタをありがとう!

EDIT:

した後、私が得たアドバイスを、次の、私はコンストラクタで(矢印関数で同じ結果を)​​をバインドし、期待通りに関数が呼び出されることを確認したが、今私が手(ありがとう!)別のエラー:

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

これは、ReactでES6を使用しているときによくある問題です。 handleClick関数をReactコンポーネントのコンテキストにバインドする必要があります。あなたは

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

    ... 

} 

またはあなたが

を呼び出した時にそれをバインドすることができますように目のコンストラクタでそれをバインドすることができ

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> 
    } 
} 

以下かのようにあなたは、コンテキストをバインドするコンポーネント定義にある矢印機能を使用することができます
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

関連する問題