React.js

【React.js】フォームの値とstateの同期を取る

こんにちは、ともです。

React.jsのチュートリアルを見ながら勉強中です。

Vue.jsだったらデータバインディングがありますが、あんな感じでstateとフォーム値を同期を取る方法についてReact.jsのチュートリアルを見ていきます。

React.jsのフォームとstateの値を同期を取る方法について書きたいと思います。

フォーム

<input name="name" value="text">

だったり、textareaselectがありますが、それらのフォームは自身にデータを保持しています。

つまり、

  1. stateの情報源
  2. フォームの情報源

の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)” とすることができています。

textareaselectも同様に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の基本が少しずつ分かってきました。とても面白いですね。