2017-02-16 17 views
0

Imは複数のボタンを作成しますが、私は押されたボタンに応じたアクションを処理する方法を知らない反応するコンポーネントを作る、これはコンポーネントです:反応小道具を介してパラメータを渡す方法?

var SingleChoiceGroup = React.createClass({ 
    render(){ 
     var numberOfButtons = this.props.numberOfButtons; 
     var prefix = this.props.prefix; 
     var buttons = []; 

     for(var i = 0;i<numberOfButtons;i++){ 
      buttons.push(
       <Button value={i} onClick={() => this.props.selectedItem(i)}>{prefix + " " + (i+1)}</Button> 
      ); 
     } 

     return(
      <div> 
       {buttons} 
      </div> 
     ) 
    } 
}); 

そして、これが法である私が取得したいし、パラメータ:

var AnotherComponent = React.createClass({ 
    selectedDay(i){ 
     // Here I want to read the index parameter from the other component. 
    }, 

    render(){ 
     <SingleChoiceGroup selectedItem={() => this.selectedDay()} numberOfButtons={7} prefix={"Text"}/> 
    }  
}); 

答えて

0

コードには2つの問題があります。最初はここにある:

<SingleChoiceGroup selectedItem={() => this.selectedDay()} numberOfButtons={7} prefix={"Text"}/> 

あなたselectedItem矢印関数は引数を取らないので、SingleChoiceGroupによってそれに渡されたi値が失われます。

あなたはselectedItem={i => this.selectedDay(i)}にそれを変更することで、これを解決できるのではなく、this.selectedDayを呼び出す関数を渡すよりも、あなただけのthis.selectedDay自体を渡すことができ、すなわち:

<SingleChoiceGroup selectedItem={this.selectedDay} numberOfButtons={7} prefix={"Text"}/> 

第二の問題を、Bartekは、彼の中で指摘したようにループの各反復で同じオブジェクトへの参照であり、最終値は7であるため、これはイベントハンドラが各ボタンに対して取得する値です。そのトピックについてのより広範な議論があるin this answer。 TL; DRはvarの代わりにletを使用して、毎回forループで新しいブロックスコープの変数を初期化します。ここで

が働いスニペットでこれらの変更の両方です:あなたSingleChoiceGroupコンポーネントの使用では

const Button = props => <button type="button" {...props}/>; 
 

 
var SingleChoiceGroup = React.createClass({ 
 
    render(){ 
 
     var numberOfButtons = this.props.numberOfButtons; 
 
     var prefix = this.props.prefix; 
 
     var buttons = []; 
 

 
     for (let i = 0; i < numberOfButtons; i++){ 
 
      buttons.push(
 
       <Button key={i} value={i} onClick={() => this.props.selectedItem(i)}>{`${prefix} ${i+1}`}</Button> 
 
      ); 
 
     } 
 
     
 
     return <div>{buttons}</div>; 
 
    } 
 
}); 
 

 
var AnotherComponent = React.createClass({ 
 
    selectedDay(i){ 
 
     console.log('clicked %d', i); 
 
    }, 
 

 
    render(){ 
 
     return <SingleChoiceGroup selectedItem={this.selectedDay} numberOfButtons={7} prefix="Text"/> 
 
    }  
 
}); 
 

 
ReactDOM.render(<AnotherComponent/>, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 
Click on us: <div id="container"></div>

+0

私はかなり反応しました。「何かをバインドする」という意味は、 'selectedItem = {this.selectedDay}'を試しましたが、 'selectedDay'メソッドで常に同じ値(7)を返します。 –

+0

あなたが言及した問題を修正し、私の答えを作業スニペットで更新しました。 「バインド」はReactの用語ではなく、JavaScriptの用語です。あなたがそれを使う必要がある理由は、ここで説明されています:https://facebook.github.io/react/docs/handling-events.html(「慎重にしてください」という段落までスクロールしてください) ) –

+0

ありがとう、今私は 'var'と' let'の違いを理解しています –

1

forループ内varlet insetadが - それ以外のハンドラがiの最後の値を使用します]をクリックあなたのケースでは7です(forループでのクロージャの詳細については、SO answerを参照してください):

for(let i = 0;i<numberOfButtons;i++){ 
     buttons.push(
      <Button value={i} onClick={() => this.props.selectedItem(i)}>{prefix + " " + (i+1)}</Button> 
     ); 
    } 
+0

完璧、ありがとう。 –

関連する問題