render
関数には、次のように単純な形式があります。
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
//How to access email and password here ?
}
Email
およびPassword
フィールドにアクセスするには、handleLogin: function() { ... }
に何を書くべきですか?
入力でchange
イベントを使用してコンポーネントの状態を更新し、handleLogin
でアクセスします。
handleEmailChange: function(e) {
this.setState({email: e.target.value});
},
handlePasswordChange: function(e) {
this.setState({password: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleEmailChange} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handlePasswordChange}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>);
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
}
実用的なフィドル: http://jsfiddle.net/kTu3a/
また、ドキュメントを読んで、フォームの取り扱いに特化したセクション全体があります。 http://facebook.github.io/react/docs/forms.html
以前はReactの双方向データバインディングヘルパーmixinを使って同じことを達成することもできましたが、今度は(上記のように)値を設定してハンドラを変更することを支持するために推奨されません。
var ExampleForm = React.createClass({
mixins: [React.addons.LinkedStateMixin],
getInitialState: function() {
return {email: '', password: ''};
},
handleLogin: function() {
console.log("EMail: " + this.state.email);
console.log("Password: " + this.state.password);
},
render: function() {
return (
<form>
<input type="text" valueLink={this.linkState('email')} />
<input type="password" valueLink={this.linkState('password')} />
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
}
});
ドキュメントはこちら: http://facebook.github.io/react/docs/two-way-binding-helpers.html
これを行うにはいくつかの方法があります。
1)フォーム要素の配列からインデックスで値を取得する
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target[0].value)
}
2)htmlでname属性を使う
handleSubmit = (event) => {
event.preventDefault();
console.log(event.target.elements.username.value) // from elements property
console.log(event.target.username.value) // or directly
}
<input type="text" name="username"/>
3)refsを使う
handleSubmit = (event) => {
console.log(this.inputNode.value)
}
<input type="text" name="username" ref={node => (this.inputNode = node)}/>
完全な例
class NameForm extends React.Component {
handleSubmit = (event) => {
event.preventDefault()
console.log(event.target[0].value)
console.log(event.target.elements.username.value)
console.log(event.target.username.value)
console.log(this.inputNode.value)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input
type="text"
name="username"
ref={node => (this.inputNode = node)}
/>
</label>
<button type="submit">Submit</button>
</form>
)
}
}
別の方法は、ref
属性を使用し、this.refs
で値を参照することです。これは簡単な例です:
render: function() {
return (<form onSubmit={this.submitForm}>
<input ref="theInput" />
</form>);
},
submitForm: function(e) {
e.preventDefault();
alert(React.findDOMNode(this.refs.theInput).value);
}
より詳しい情報はReactのドキュメントにあります: https://facebook.github.io/react/docs/more-about-refs.html#the-ref-string-attribute
Reactでラジオボタンを使うにはどうすればいいですか? この方法は常に最善ではありませんが、役に立ちます。いくつかの単純なケースでは代替手段。
参照を処理する簡単な方法:
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const formData = {};
for (const field in this.refs) {
formData[field] = this.refs[field].value;
}
console.log('-->', formData);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input ref="phone" className="phone" type='tel' name="phone"/>
<input ref="email" className="email" type='tel' name="email"/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default UserInfo;
私は以下のアプローチを提案します:
import {Autobind} from 'es-decorators';
export class Form extends Component {
@Autobind
handleChange(e) {
this.setState({[e.target.name]: e.target.value});
}
@Autobind
add(e) {
e.preventDefault();
this.collection.add(this.state);
this.refs.form.reset();
}
shouldComponentUpdate() {
return false;
}
render() {
return (
<form onSubmit={this.add} ref="form">
<input type="text" name="desination" onChange={this.handleChange}/>
<input type="date" name="startDate" onChange={this.handleChange}/>
<input type="date" name="endDate" onChange={this.handleChange}/>
<textarea name="description" onChange={this.handleChange}/>
<button type="submit">Add</button>
</form>
)
}
}
ボタンのonClick
イベントハンドラをフォームのonSubmit
ハンドラに切り替えることができます。
render : function() {
return (
<form onSubmit={this.handleLogin}>
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
それからFormData
を利用してフォームを解析することができます(そして必要ならばそのエントリーからJSONオブジェクトを構築することもできます)。
handleLogin: function(e) {
const formData = new FormData(e.target)
const user = {}
e.preventDefault()
for (let entry of formData.entries()) {
user[entry[0]] = entry[1]
}
// Do what you will with the user object here
}
すべての入力/テキストエリアに名前がある場合は、event.targetからすべてをフィルタリングできます。
onSubmit(event){
const fields = Array.prototype.slice.call(event.target)
.filter(el => el.name)
.reduce((form, el) => ({
...form,
[el.name]: el.value,
}), {})
}
まったく制御されていない形式onChangeメソッド、値、defaultValueがない場合.
また、これも使えます。
handleChange: function(state,e) {
this.setState({[state]: e.target.value});
},
render : function() {
return (
<form>
<input type="text" name="email" placeholder="Email" value={this.state.email} onChange={this.handleChange.bind(this, 'email')} />
<input type="password" name="password" placeholder="Password" value={this.state.password} onChange={this.handleChange.bind(this, 'password')}/>
<button type="button" onClick={this.handleLogin}>Login</button>
</form>
);
},
handleLogin: function() {
console.log("EMail: ", this.state.email);
console.log("Password: ", this.state.password);
}
このようにあなたの入力refを与えなさい
<input type="text" name="email" placeholder="Email" ref="email" />
<input type="password" name="password" placeholder="Password" ref="password" />
それならあなたはsooのようにあなたのhandleLoginでそれにアクセスすることができます
handleLogin: function(e) {
e.preventDefault();
console.log(this.refs.email.value)
console.log(this.refs.password.value)
}
プロジェクトでReduxを使用している場合は、この高次コンポーネント https://github.com/erikras/redux-form を使用することを検討できます。
onChange(event){
console.log(event.target.value);
}
handleSubmit(event){
event.preventDefault();
const formData = {};
for (const data in this.refs) {
formData[data] = this.refs[data].value;
}
console.log(formData);
}
<form onSubmit={this.handleSubmit.bind(this)}>
<input type="text" ref="username" onChange={this.onChange} className="form-control"/>
<input type="text" ref="password" onChange={this.onChange} className="form-control"/>
<button type="submit" className="btn-danger btn-sm">Search</button>
</form>
Javascriptの多くのイベントでは、event
があります。これは、どのイベントが発生したのか、値は何なのかなど、オブジェクトを表します。
それが私たちがReactJのフォームでも使うものです...
それであなたのコードであなたは新しい値に状態を設定します...このような何か:
class UserInfo extends React.Component {
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
}
handleLogin(e) {
e.preventDefault();
for (const field in this.refs) {
this.setState({this.refs[field]: this.refs[field].value});
}
}
render() {
return (
<div>
<form onSubmit={this.handleLogin}>
<input ref="email" type="text" name="email" placeholder="Email" />
<input ref="password" type="password" name="password" placeholder="Password" />
<button type="button">Login</button>
</form>
</div>
);
}
}
export default UserInfo;
また、これはReact v.16のフォームの例です。将来作成するフォームの参照として使用してください。
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
Michael Schockの答えに加えて:
class MyForm extends React.Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
const data = new FormData(event.target);
console.log(data.get('email')); // reference by form input's `name` tag
fetch('/api/form-submit-url', {
method: 'POST',
body: data,
});
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="username">Enter username</label>
<input id="username" name="username" type="text" />
<label htmlFor="email">Enter your email</label>
<input id="email" name="email" type="email" />
<label htmlFor="birthdate">Enter your birth date</label>
<input id="birthdate" name="birthdate" type="text" />
<button>Send data!</button>
</form>
);
}
}
この中級記事を参照してください。フォームを正しく処理する方法
このメソッドは、送信ボタンが押されたときにのみフォームデータを取得します。もっときれいなIMO!
これはMeteor(v1.3)ユーザーに役立つかもしれません:
render: function() {
return (
<form onSubmit={this.submitForm.bind(this)}>
<input type="text" ref="email" placeholder="Email" />
<input type="password" ref="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
);
},
submitForm: function(e) {
e.preventDefault();
console.log( this.refs.email.value );
console.log( this.refs.password.value );
}
Es6を破壊する より明確な例
class Form extends Component {
constructor(props) {
super(props);
this.state = {
login: null,
password: null,
email: null
}
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value
})
}
onSubmit(e) {
e.preventDefault();
let login = this.state.login;
let password = this.state.password;
// etc
}
render() {
return (
<form onSubmit={this.onSubmit.bind(this)}>
<input type="text" name="login" onChange={this.onChange.bind(this)} />
<input type="password" name="password" onChange={this.onChange.bind(this)} />
<input type="email" name="email" onChange={this.onChange.bind(this)} />
<button type="submit">Sign Up</button>
</form>
);
}
}
要素名が複数ある場合は、forEach()を使用する必要があります。
html
<input type="checkbox" name="delete" id="flizzit" />
<input type="checkbox" name="delete" id="floo" />
<input type="checkbox" name="delete" id="flum" />
<input type="submit" value="Save" onClick={evt => saveAction(evt)}></input>
js
const submitAction = (evt) => {
evt.preventDefault();
const dels = evt.target.parentElement.delete;
const deleted = [];
dels.forEach((d) => { if (d.checked) deleted.Push(d.id); });
window.alert(deleted.length);
};
この場合のdelは配列ではなくRadioNodeListであり、Iterableではないことに注意してください。 forEach()はリストクラスの組み込みメソッドです。ここでmap()やreduce()を使うことはできません。
ユーザーエクスペリエンスを向上させるためユーザーが送信ボタンをクリックすると、送信メッセージを最初に表示するようにフォームを取得しようとすることができます。サーバーから応答があると、それに応じてメッセージを更新できます。私たちはReactの中でステータスをチェーニングすることによってこれを達成します。以下の codepen またはスニペットを参照してください。
次のメソッドは最初の状態を変更します。
handleSubmit(e) {
e.preventDefault();
this.setState({ message: 'Sending...' }, this.sendFormData);
}
Reactが上記のSendingメッセージを画面に表示するとすぐに、フォームデータをサーバーに送信するメソッドthis.sendFormData()を呼び出します。簡単にするために、これを模倣するためにsetTimeoutを追加しました。
sendFormData() {
var formData = {
Title: this.refs.Title.value,
Author: this.refs.Author.value,
Genre: this.refs.Genre.value,
YearReleased: this.refs.YearReleased.value};
setTimeout(() => {
console.log(formData);
this.setState({ message: 'data sent!' });
}, 3000);
}
Reactでは、this.setState()メソッドはコンポーネントに新しいプロパティをレンダリングします。そのため、フォームコンポーネントのrender()メソッドに、サーバーから取得する応答の種類に応じて動作が異なるロジックを追加することもできます。例えば:
render() {
if (this.state.responseType) {
var classString = 'alert alert-' + this.state.type;
var status = <div id="status" className={classString} ref="status">
{this.state.message}
</div>;
}
return ( ...
私はReact Component状態を使ってこのように使います:
<input type="text" name='value' value={this.state.value} onChange={(e) => this.handleChange(e)} />
handleChange(e){
this.setState({[e.target.name]: e.target.value})
}`