こんにちは、ともです。
React.jsのチュートリアルを見ながら勉強中です。
Vue.jsだったらデータバインディングがありますが、あんな感じでstateとフォーム値を同期を取る方法についてReact.jsのチュートリアルを見ていきます。
React.jsのフォームとstateの値を同期を取る方法について書きたいと思います。
フォーム
<input name="name" value="text">
だったり、textarea
やselect
がありますが、それらのフォームは自身にデータを保持しています。
つまり、
- stateの情報源
- フォームの情報源
の2種類が存在した状態になります。
しかし、React の state を “信頼できる唯一の情報源 (single source of truth)” とすることで、上述の 2 つの状態を結合させることができます。
このようにstateを信頼できる唯一の情報源とすることで作成されたコンポーネントを制御されたコンポーネントと呼びます。
制御されたコンポーネントの作成
class InputForm extends React.Component {
constructor (props) {
super(props)
this.state = {value: ''}
this.handleChange = this.handleChange.bind(this)
}
handleChange (e) {
this.setState({value: e.target.value})
}
render () {
return (
<div>
<p>ステートの値:{this.state.value}</p>
<input value={this.state.value} onChange={this.handleChange} />
</div>
)
}
}
ReactDOM.render(
<InputForm/>,
document.getElementById('root')
)
inputのフィールドが変化した際にstateに保存するようにイベントハンドラを作成します。
inputタグはstateの情報を表示することにより、state を “信頼できる唯一の情報源 (single source of truth)” とすることができています。
textarea
やselect
も同様にstateを”信頼できる唯一の情報源”とすることで制御されたコンポーネントを作成することが可能です。
複数のフォームが存在する場合
stateのキー名をフォームのnameにすることにより、複数フォームが存在するコンポーネント内でも制御されたコンポーネントを作成することが可能です。
class SomeForms extends React.Component {
constructor (props) {
super(props)
this.state = {title: '', content: ''} // stateのkey名とフォームのname属性を一致させる
this.handleChange = this.handleChange.bind(this)
}
handleChange (e) {
let name = e.target.name; // フォームのname属性を取得
this.setState({[name]: e.target.value}) // name属性 = stateのkey名なのでstateに保存
}
render () {
return (
<div>
<p>titleの値:{this.state.title}</p>
<p>textの値:{this.state.text}</p>
<input name="title" value={this.state.title} onChange={this.handleChange} />// nameをkeyに一致
<textarea name="text" onChange={this.handleChange}>{this.state.text}</textarea>// nameをkeyに一致
</div>
)
}
}
フォームのname属性とstateのkeyを一致させておくことにより、1つのイベントハンドラでstateを更新することができています。
まとめ
制御されたコンポーネントについて書きました。stateを唯一の情報源とすることで制御されたコンポーネントを作成する方法でした。
React.jsの基本が少しずつ分かってきました。とても面白いですね。