2016-08-27 8 views
7

私は非常に簡単な反応アプリを作っています。しかし、onChangeイベントを介してparent(実際に祖父母)メソッドのメソッドを呼び出そうとすると、私はUncaught TypeError: Cannot read property 'props' of undefinedを取得し続けます。React.js - 未定義のプロパティを読み取ることができません

これはイベントをトリガーするコンポーネント/フォームです(バインドされた親コンポーネントのメソッドを呼び出す...はい、私は親コンポーネントから小道具を経由してメソッドに.boundを使用しました)。

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

ここでは、ほとんどの親(祖父母)コンポーネントからメソッドを渡す方法を示します。あなたが最初に見たコンポーネント(MonthsTable)に渡された

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

(メソッドの所有者とメソッド呼び出しの間にあるコンポーネント)私は親で小道具としてメソッドを渡す方法です

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

そして最後に。 Wheter関連性があるかどうか、最終的な(ほとんどの子)コンポーネントは、うまく動作するif文に応じて表示されます(何らかの形で関係するかもしれませんが、わかりません)。 (handleChangeOnMonth)メソッドの中で(setMonth)メソッドが '見えない'のはなぜですか?

ありがとうございました。

+0

'this.handleChangeOnMonth'を' this'にバインドしてみますか? –

答えて

5

ここでの実際の問題は、handleChangeOnMonth関数でthisコンテキストが定義されていないことです。これは、javascriptが関数のコンテキストを処理する方法(基本的には、オブジェクトから直接呼び出さない関数を呼び出すときに関数を処理する方法と、定義されていないコンテキストにバインドされていないため、関数を渡すために発生します入力コンポーネントへのパラメータとして、コンテキストを失います。

この問題を解決する最も簡単な方法は、関数をバインドすることで、私はあなたがそうのように、コンストラクタ内の関数をバインドすることを示唆している:

代わり
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>) 
    } 
} 

あなたはあなたにcore-decoratorsパッケージを使用することができデコレータを使用している場合、

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>) 
    } 
} 
関連する問題