これにアプローチする正しい方法は何ですか?
var Hello = React.createClass({
getInitialState: function() {
return {total: 0, input1:0, input2:0};
},
render: function() {
return (
<div>{this.state.total}<br/>
<input type="text" value={this.state.input1} onChange={this.handleChange} />
<input type="text" value={this.state.input2} onChange={this.handleChange} />
</div>
);
},
handleChange: function(e){
this.setState({ ??? : e.target.value});
t = this.state.input1 + this.state.input2;
this.setState({total: t});
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
明らかに、それぞれ異なる入力を処理するために別個のhandleChange関数を作成できますが、それはあまり良いことではありません。同様に、個々の入力のためだけにコンポーネントを作成することもできますが、このようにする方法があるかどうかを見たかったのです。
name
要素の input
のような標準のHTML属性を使用して、入力を識別することをお勧めします。また、状態に別の値を追加することで構成できるため、「total」を状態の個別の値として保持する必要はありません。
var Hello = React.createClass({
getInitialState: function() {
return {input1: 0, input2: 0};
},
render: function() {
const total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" value={this.state.input1} name="input1" onChange={this.handleChange} />
<input type="text" value={this.state.input2} name="input2" onChange={this.handleChange} />
</div>
);
},
handleChange: function(e) {
this.setState({[e.target.name]: e.target.value});
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
.bind
メソッドを使用して、handleChange
メソッドのパラメーターを事前に構築できます。次のようなものになります。
var Hello = React.createClass({
getInitialState: function() {
return {input1:0,
input2:0};
},
render: function() {
var total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" value={this.state.input1}
onChange={this.handleChange.bind(this, 'input1')} />
<input type="text" value={this.state.input2}
onChange={this.handleChange.bind(this, 'input2')} />
</div>
);
},
handleChange: function (name, e) {
var change = {};
change[name] = e.target.value;
this.setState(change);
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
(推奨されることなので、レンダリング時にtotal
を計算するようにしました。)
onChange
イベントのバブル...したがって、次のようなことができます。
// A sample form
render () {
<form onChange={setField}>
<input name="input1" />
<input name="input2" />
</form>
}
SetFieldメソッドは次のようになります(ES2015以降を使用している場合:
setField (e) {
this.setState({[e.target.name]: e.target.value})
}
これに似たものをいくつかのアプリで使用していますが、とても便利です。
valueLink/checkedLink
は、一部のユーザーを混乱させるため、コアReactから 非推奨 です。 Reactの最新バージョンを使用している場合、この回答は機能しません。しかし、あなたがそれを好めば、あなたはあなた自身のInput
コンポーネントを作成することで簡単にエミュレートできます
Reactの2方向データバインディングヘルパーを使用すると、達成したいことをはるかに簡単に達成できます。
var Hello = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {input1: 0, input2: 0};
},
render: function() {
var total = this.state.input1 + this.state.input2;
return (
<div>{total}<br/>
<input type="text" valueLink={this.linkState('input1')} />;
<input type="text" valueLink={this.linkState('input2')} />;
</div>
);
}
});
React.renderComponent(<Hello />, document.getElementById('content'));
簡単でしょう?
http://facebook.github.io/react/docs/two-way-binding-helpers.html
このようにすることもできます:
...
constructor() {
super();
this.state = { input1: 0, input2: 0 };
this.handleChange = this.handleChange.bind(this);
}
handleChange(input, value) {
this.setState({
[input]: value
})
}
render() {
const total = this.state.input1 + this.state.input2;
return (
<div>
{total}<br />
<input type="text" onChange={e => this.handleChange('input1', e.target.value)} />
<input type="text" onChange={e => this.handleChange('input2', e.target.value)} />
</div>
)
}
React
という特別なref
属性を使用し、onChange
のgetDOMNode()
関数を使用して、React
イベントの実際のDOMノードと一致させることができます。
handleClick: function(event) {
if (event.target === this.refs.prev.getDOMNode()) {
...
}
}
render: function() {
...
<button ref="prev" onClick={this.handleClick}>Previous question</button>
<button ref="next" onClick={this.handleClick}>Next question</button>
...
}
@Vigril Disgr4ce
マルチフィールドフォームに関しては、Reactの主要な機能であるコンポーネントを使用するのが理にかなっています。
私のプロジェクトでは、TextFieldコンポーネントを作成します。これは、少なくとも値の小道具を取り、入力テキストフィールドの一般的な動作を処理します。これにより、値の状態を更新するときにフィールド名を追跡することを心配する必要がなくなります。
[...]
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function() {
var value = this.state.value;
return <input type="text" value={value} onChange={this.handleChange} />;
}
[...]
単一のinput
name__の値を管理する個別のInputField
name__コンポーネントを作成することにより、各子input
name__の値を追跡できます。たとえば、InputField
name__は次のようになります。
var InputField = React.createClass({
getInitialState: function () {
return({text: this.props.text})
},
onChangeHandler: function (event) {
this.setState({text: event.target.value})
},
render: function () {
return (<input onChange={this.onChangeHandler} value={this.state.text} />)
}
})
これで、各input
name__の値は、このInputField
name__コンポーネントの個別のインスタンス内で追跡でき、各子コンポーネントを監視するために親の状態で個別の値を作成する必要はありません。