2017-05-07 5 views
2

저는 Egghead를 통해 "첫 프로덕션 품질의 React 앱 만들기"를 마치고 context을 사용하여 가정용으로 만든 17 번째 수업까지 모든 것이 잘 진행됩니다. 라우터 구성 요소. 지금까지 내가 말할 수있는, 나는 수업에서 정확히 같은 일을하지만, 나는 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> 
    } 
} 

문제의 원인이 될 수 있는지의 어떤 생각?

올바른 방향으로 어떤 포인터 주셔서 감사합니다!

편집 :

후 내가받은 조언에 따라, 나는 생성자 (화살표 기능과 같은 결과를)을 handleClick 바인딩 예상대로 함수가 호출되는 것을 확인하지만, 지금은 수 (감사합니다!) 다른 오류 :

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을 사용하는 경우 자주 발생하는 문제입니다. 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

관련 문제