https://qiita.com/y_ohr/items/3edf241c5ac1952afd05 の続きです。
環境
Ubuntu 18.04.2 LTS
node v8.10.0
npm 3.5.2
create-react-app v2.1.5
3行まとめ
- Reactのjsxで、inputのtextにprop.valueを設定した
- しかし、動かしてみたらUIからinputの値を変更できなかった
- stateを使用したら、変更できるようになった
調べる
公式ドキュメントのフォーム項を読む。
https://ja.reactjs.org/docs/forms.html
- 制御されたコンポーネント
HTML では
<input>
、<textarea>
、そして<select>
のようなフォーム要素は通常、自身で状態を保持しており、ユーザーの入力に基づいてそれを更新します。React では、変更されうる状態は通常はコンポーネントの state プロパティに保持され、setState()
関数でのみ更新されます。
React の state を “信頼できる唯一の情報源 (single source of truth)” とすることで、上述の 2 つの状態を結合させることができます。そうすることで、フォームをレンダーしている React コンポーネントが、後続するユーザー入力でフォームで起きることも制御できるようになります。このような方法で React によって値が制御される入力フォーム要素は「制御されたコンポーネント」と呼ばれます。
なるほど。つまり・・・
- inputのvalueはstateから設定する
- stateを変更するとvalueに反映される
- inputのonchangeでstateを変更する
- stateは
setState()
で設定する
という理解。
inputのvalueをstateで設定するように修正
src/index.js
diff --git a/src/index.js b/src/index.js
index 8d285cc..7f4962d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,12 +2,18 @@ import React from 'react';
import ReactDOM from 'react-dom';
class Square extends React.Component {
+ constructor(prop) {
+ super(prop);
+ this.state = { value: prop.value };
+ }
+
render() {
return (
<input
type="text"
- value={this.props.value}
+ value={this.state.value}
className="square"
+ onChange={e => this.setState({ value: e.target.value })}
>
</input>
);
上記で動かしたら、UIから値を変更できるようになりました
感想
- 次は複数のinputを連動させたい
- 親子コンポーネントでそれぞれonChange()をハンドルしていると、両方発火する?発火する場合、順番は?
- 今回は未使用だけど、公式のフォームDocs例にある、コンストラクタの
this.handleChange = this.handleChange.bind(this)
と<input type="text" value={this.state.value} onChange={this.handleChange} />
は、一見冗長に見える - ReactのDocsやTutorialの公式日本語があるのを知らなかった・・・
以上