2017-05-07 9 views
2

Ich habe durch den Egghead "Build Ihre erste Produktion Qualität React App" und alles läuft gut, bis Lektion 17, wo Sie context verwenden sollen, um Ihre eigenen Haus gemacht zu erstellen Router-Komponente. Soweit ich das beurteilen kann, mache ich genau das Gleiche wie in der Lehre, aber ich bekomme diese Fehlerkonsole, wenn ich auf einem der Komponente Link klicken:Kann nicht lesen Eigenschaft 'Kontext' von Null

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) 

Die Link-Komponente wie das aussieht:

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 
} 

Und die Router-Komponente sieht wie folgt aus:

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

Jede Idee, was das Problem verursacht werden könnte?

Danke für jeden Zeiger in die richtige Richtung!

EDIT:

Nach den Ratschlägen folgenden ich habe, gebunden ich die handleClick in einem Konstruktor (gleiches Ergebnis mit einer Pfeil-Funktion) und überprüfte, dass die Funktion wie erwartet genannt wird, aber jetzt bekomme ich (danke!) ein anderer Fehler:

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

Sie müssen dies handle binden. Sie können dies entweder in einem Konstruktor oder in onClick tun (nicht empfohlen). onClick = {this.handleClick.bind (this)}. Oder verwenden Sie eine Pfeilfunktion für handleClick. const handleClick =() => {}. –

+0

^^ Dies ist die Antwort auf die gestellte Frage. – Jason

Antwort

0

Dies ist ein häufiges Problem, wenn Sie ES6 mit React verwenden. Sie müssen die handleClick-Funktion an den Kontext der React-Komponente binden. Sie können Pfeil Funktion auf Komponentendefinition verwenden, den Kontext zu binden, wie unter

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

oder Sie können es in th Konstruktor binden wie

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

    ... 

} 

oder Sie können es an der Zeit binden von

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

or 

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

Zusätzlich zu der Notwendigkeit, eine Funktion an this zu binden, kann dieser Fehler auch auftreten, wenn Sie eine Funktion gebunden haben, die nicht mehr in der Klasse vorhanden ist:

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

    // functionDoesNotExistAnymore() {} 
} 
0

Um eine klare Antwort auf diese Frage zu geben, haben die anderen eine Menge zusätzlicher Informationen, die Sie in die Irre führen können.

Zitiert

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 (aus den Kommentaren)

Verwandte Themen