私は最近ReactJS
の使用を開始しました。具体的には、react-Rails
Ruby gemおよびreact-bootstrap
コンポーネントを利用しています。
onClick
イベントリスナーを子コンポーネントに配置することに関して質問があります。
以下のコードサンプルからわかるように、render
関数で子コンポーネントを「呼び出す」親コンポーネントがあります。そのrender
関数内には、クリックされたときにonClick
を呼び出すReact handleToggle
リスナーがあります。
###* @jsx React.DOM ###
ToggleIconButton = React.createClass
getInitialState: ->
toggleOn: false
handleToggle: (evt) ->
this.setState(toggleOn: !this.state.toggleOn)
render: ->
`<IconButton onClick={this.handleToggle}>Toggle Button</IconButton>`
IconButton = React.createClass
render: ->
# BsButton and BsGlyphicon are React-Bootstrap components
`<BsButton>
<BsGlyphicon glyph={this.props.glyph} />
{" " + this.props.text}
</BsButton>`
残念ながら、これは思ったようには機能しません。 ToggleIconButton::handleToggle
は呼び出されません。代わりに、onClick
リスナーがIconButton
に配置され、ToggleIconButton::handleToggle
を参照します。
IconButton
に追加の動作を追加したくありません。私の考えでは、IconButton
に条件付きロジックを配置する必要はありません。すべきことは、アイコンとボタンを表すことだけで、ブラウザイベントを心配する必要はありません。それがToggleIconButton
の目的です。
React Div
をIconButton
で囲み、そこにonClick
リスナーを書くことができることは知っていますが(これを試してみましたが、動作します)、それは少しジャンキーなようです。
誰かがこれを行う良い方法を知っていますか?みんなありがとう!
したがって、この場合のイベント処理の適切な方法は、イベントハンドラーを子コンポーネントに渡すことです。あなたが望むものを達成するいくつかの方法があり、この動作を異なる方法で実装するかもしれません(ユースケースがわからない)が、親コンポーネントと子コンポーネント間の典型的なイベント処理を示すJSXの例を用意しました。ここで見つけることができます...
次のように考えてください:
var ParentComponent = React.createClass({
render: function(){
return (
<ChildComponent onSomeEvent={this.handleThatEvent} />;
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
var ChildComponent = React.createClass({
render: function(){
return (
<input type="button" onClick={this.props.onSomeEvent} value="Click Me!" />
)
}
});
ノードを呼び出す前に、レンダーのthisを参照するvarを作成する場合、子コンポーネントを作成する必要はありません。
var self = this;
そのため、たとえば(これは考案されており、この場合var selfは必要ありませんが、ネストされたreturnステートメントの場合は必要になります)。
var ParentComponent = React.createClass({
render: function(){
var self = this;
return (
<input type="button" onClick={self.handleThatEvent} value="Click Me!" />;
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
さらに良いことに、これを関数にバインドできます。
var ParentComponent = React.createClass({
render: function(){
return (
this.state.array.map(function(){
return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
}.bind(this));
)
},
handleThatEvent: function(e){
//update state, etc.
}
});
または、コメントでcaptrayの提案に従う
var ParentComponent = React.createClass({
render: function(){
return (
this.state.array.map(function(){
return (<input type="button" onClick={this.handleThatEvent} value="Click Me!" />);
}, this);
)
},
handleThatEvent: function(e){
//update state, etc.
}
});