2016-08-27 5 views
7

매우 간단한 반응 앱을 만들고 있습니다. 그러나 onChange 이벤트를 통해 parent (실제로 조부모) 컴포넌트의 메소드를 호출하려고 시도 할 때 나는 계속 Uncaught TypeError: Cannot read property 'props' of undefined을 얻는다.React.js - 정의되지 않은 속성을 읽을 수 없습니다.

다음은 이벤트를 트리거하는 구성 요소/폼입니다 (따라서 바인딩 된 부모 구성 요소에서 메소드를 호출합니다 ...). 예. 부모 구성 요소에서 소품을 통해 전달할 때 메소드에서 .bound (this)를 사용했습니다.

class MonthsTable extends Component { 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); // here the method is not found, causing error. 
    } 
    render(){ 
    console.log(this.props.setMonth) // here the method is present alright 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} // yes I know, bad habit, but in this case it doesn't matter 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 

다음은 대부분의 부모 (조부모) 구성 요소의 소품으로 메서드를 전달하는 방법입니다. 여기

<Months setMonth={this.setMonth.bind(this)} /> 

내가 부모에

<MonthsTable setMonth={this.props.setMonth} /> 

그리고 마지막 구성 요소를 처음 보았다 (MonthsTable)에 전달 (방법 소유자 및 방법 호출자 사이에 구성 요소를) 소품 등의 방법을 전달하는 방법이다 . Wheter 관련성 여부와 관계없이 최종 (대부분의 자식) 구성 요소는 잘 작동하는 if 문에 따라 표시됩니다 (어쨌든 관련성이 있을지 모르지만).

질문 : 왜 (setMonth) 메서드가 (handleChangeOnMonth) 메서드 내부에서 '보이지 않음'입니까?

어떤 조언을 주셔서 감사합니다.

+0

'this.handleChangeOnMonth'을 (를)'this '에 바인딩 해보세요. –

답변

5

여기 실제 문제는 handleChangeOnMonth 함수에 this 컨텍스트가 정의되어 있지 않다는 것입니다. 이것은 javascript가 함수의 컨텍스트를 처리하는 방식으로 인해 발생합니다. 기본적으로 함수를 호출 할 때 함수를 호출 할 때 함수를 호출 할 때 발생하며, 바인딩되지 않은 경우에는 정의 된 컨텍스트가 없으므로 함수를 전달하고 있기 때문에 발생합니다 입력 구성 요소에 대한 매개 변수로 문맥을 잃습니다. 당신이 장식을 사용하는 경우에 core-decorators 패키지를 사용할 수있는 다른 방법

class MonthsTable extends Component { 
    constructor(props, context){ 
    super(props, context); 
    this.handleChangeOnMonth = this.handleChangeOnMonth.bind(this); 
    } 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); 
    } 
    render(){ 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 

:

이 문제를 해결하는 가장 간단한 방법은 당신이, 생성자의 기능을 결합과 같이 제안, 기능을 결합하는 것입니다 더 우아한 방법으로 이것을하십시오 :

import {autobind} from "core-decorators" 

@autobind 
class MonthsTable extends Component {  
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); 
    } 
    render(){ 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth} />)} 
    </form>) 
    } 
} 
0

당신은 onChange에 당신의 기능을 현재 문맥에 바인딩해야합니다. 클래스의 생성자에서 바인딩 할 수도 있고, 좋은 연습이 아닌 onChange()에 직접 바인드 할 수도 있습니다.

class MonthsTable extends Component { 
    constructor(props){ 
    super(props); 
    this.handleChangeOnMonth = this.handleChangeOnMonth.bind(this); 
    } 
    handleChangeOnMonth(e){ 
    this.props.setMonth(e.target.id, e.target.value); // here the method is not found, causing error. 
    } 
    render(){ 
    console.log(this.props.setMonth) // here the method is present alright 
    return (<form> 
     {this.props.months.map((e, i) => 
     <input 
      type='number' 
      id={i} 
      key={i} // yes I know, bad habit, but in this case it doesn't matter 
      value={this.props.months[i]} 
      onChange={this.handleChangeOnMonth.bind(this)} />)} 
    </form>) 
    } 
} 
관련 문제