Help us understand the problem. What is going on with this article?

Reactのinput(複数inputで成功)

More than 1 year has passed since last update.

https://qiita.com/y_ohr/items/ecfaf31176c3ad554bf2 の続きです。

環境

Ubuntu 18.04.2 LTS
node v8.10.0
npm 3.5.2
create-react-app v2.1.5

3行まとめ

  • 複数のinputを連動させるためstateを、親コンポーネントへリフトアップした
  • 合わせてsetState()も、親コンポーネントへリフトアップし、子のhandleChangeで発火するようにした
  • 複数のinputが連動できた

複数inputが連動するように修正

src/index.js
--- a/src/index.js
+++ b/src/index.js
@@ -4,18 +4,20 @@ import ReactDOM from 'react-dom';
 class Square extends React.Component {
     constructor(props) {
         super(props);
-        this.state = {
-            value: props.value
-        }
+        this.handleChange = this.handleChange.bind(this);
+    }
+
+    handleChange(e){
+        this.props.onNumberChange(e.target.value);
     }

     render() {
         return (
             <input
                 type="text"
-                value={this.state.value}
+                value={this.props.number}
                 className="square"
-                onChange={e => this.setState({ value: e.target.value })}
+                onChange={this.handleChange}
             >
             </input>
         );
@@ -23,36 +25,83 @@ class Square extends React.Component {
 }

 class Board extends React.Component {
-    renderSquare(i) {
-        return <Square value={i} />;
+    constructor(props) {
+        super(props);
+
+        this.handleX1Change = this.handleX1Change.bind(this);
+        this.handleY1Change = this.handleY1Change.bind(this);
+        this.handleX2Change = this.handleX2Change.bind(this);
+        this.handleY2Change = this.handleY2Change.bind(this);
+        this.handleX3Change = this.handleX3Change.bind(this);
+        this.handleY3Change = this.handleY3Change.bind(this);
+
+        this.state = {
+            x1: 0, y1: 1,
+            x2: 3, y2: 4,
+            x3: 6, y3: 7,
+         };
+    }
+
+    handleX1Change(x1) {
+        this.setState({ x1 });
+    }
+
+    handleY1Change(y1) {
+        this.setState({ y1 });
+    }
+
+    handleX2Change(x2) {
+        this.setState({ x2 });
+    }
+
+    handleY2Change(y2) {
+        this.setState({ y2 });
+    }
+
+    handleX3Change(x3) {
+        this.setState({ x3 });
+    }
+
+    handleY3Change(y3) {
+        this.setState({ y3 });
+    }
+
+    renderSquare(i, m) {
+        return <Square number={i} onNumberChange={m} />;
     }

     render() {
-        const status = 'Next player: X';
+        const title = 'XY<E5><8A><A0><E7><AE><97><E6><A9><9F>';
+        const sum1 = parseInt(this.state.x1, 10) + parseInt(this.state.y1, 10);
+        const sum2 = parseInt(this.state.x2, 10) + parseInt(this.state.y2, 10);
+        const sum3 = parseInt(this.state.x3, 10) + parseInt(this.state.y3, 10);

         return (
             <div>
-                <div className="status">{status}</div>
+                <div className="title">{title}</div>
                 <div className="board-row">
-                    {this.renderSquare(0)}
+                    1
+                    {this.renderSquare(this.state.x1, this.handleX1Change)}
                     +
-                    {this.renderSquare(1)}
+                    {this.renderSquare(this.state.y1, this.handleY1Change)}
                     =
-                    {this.renderSquare(1)}
+                    {this.renderSquare(sum1)}
                 </div>
                 <div className="board-row">
-                    {this.renderSquare(3)}
+                    2
+                    {this.renderSquare(this.state.x2, this.handleX2Change)}
                     +
-                    {this.renderSquare(4)}
+                    {this.renderSquare(this.state.y2, this.handleY2Change)}
                     =
-                    {this.renderSquare(7)}
+                    {this.renderSquare(sum2)}
                 </div>
                 <div className="board-row">
-                    {this.renderSquare(6)}
+                    3
+                    {this.renderSquare(this.state.x3, this.handleX3Change)}
                     +
-                    {this.renderSquare(7)}
+                    {this.renderSquare(this.state.y3, this.handleY3Change)}
                     =
-                    {this.renderSquare(13)}
+                    {this.renderSquare(sum3)}
                 </div>
             </div>
         );

複数コンポーネントが連動した!
image.png

感想

  • どう見ても冗長なので何とかしたい
  • 子から親へのonChangeのイメージが乏しい
  • 当初、sumはstateにしていたが、stateのxとyから算出できるので、stateはやめた
  • sumの計算は静的に見えるが、state更新時に動的に計算される
  • stateが更新されるとrender()が実行され、結果の差分のみレンダリングされる?
  • 縦合計も出したい
  • 四則演算に対応したい

以上

y_ohr
投稿する意見や活動内容は私個人の見解に基づくものであり、所属企業・部門見解を代表するものではありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away